test_excellon_flow.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import unittest
  2. from PyQt5 import QtGui, QtWidgets
  3. import sys
  4. from FlatCAMApp import App
  5. from FlatCAMObj import FlatCAMExcellon, FlatCAMCNCjob
  6. from flatcamGUI.ObjectUI import ExcellonObjectUI
  7. import tempfile
  8. import os
  9. from time import sleep
  10. class ExcellonFlowTestCase(unittest.TestCase):
  11. """
  12. This is a top-level test covering the Excellon-to-GCode
  13. generation workflow.
  14. THIS IS A REQUIRED TEST FOR ANY UPDATES.
  15. """
  16. filename = 'case1.drl'
  17. def setUp(self):
  18. self.app = QtWidgets.QApplication(sys.argv)
  19. # Create App, keep app defaults (do not load
  20. # user-defined defaults).
  21. self.fc = App(user_defaults=False)
  22. self.fc.open_excellon('tests/excellon_files/' + self.filename)
  23. def tearDown(self):
  24. del self.fc
  25. del self.app
  26. def test_flow(self):
  27. # Names of available objects.
  28. names = self.fc.collection.get_names()
  29. print(names)
  30. #--------------------------------------
  31. # Total of 1 objects.
  32. #--------------------------------------
  33. self.assertEqual(len(names), 1,
  34. "Expected 1 object, found %d" % len(names))
  35. #--------------------------------------
  36. # Object's name matches the file name.
  37. #--------------------------------------
  38. self.assertEqual(names[0], self.filename,
  39. "Expected name == %s, got %s" % (self.filename, names[0]))
  40. #---------------------------------------
  41. # Get object by that name, make sure it's a FlatCAMExcellon.
  42. #---------------------------------------
  43. excellon_name = names[0]
  44. excellon_obj = self.fc.collection.get_by_name(excellon_name)
  45. self.assertTrue(isinstance(excellon_obj, FlatCAMExcellon),
  46. "Expected FlatCAMExcellon, instead, %s is %s" %
  47. (excellon_name, type(excellon_obj)))
  48. #----------------------------------------
  49. # Object's GUI matches Object's options
  50. #----------------------------------------
  51. # TODO: Open GUI with double-click on object.
  52. # Opens the Object's GUI, populates it.
  53. excellon_obj.build_ui()
  54. for option, value in list(excellon_obj.options.items()):
  55. try:
  56. form_field = excellon_obj.form_fields[option]
  57. except KeyError:
  58. print(("**********************************************************\n"
  59. "* WARNING: Option '{}' has no form field\n"
  60. "**********************************************************"
  61. "".format(option)))
  62. continue
  63. self.assertEqual(value, form_field.get_value(),
  64. "Option '{}' == {} but form has {}".format(
  65. option, value, form_field.get_value()
  66. ))
  67. # --------------------------------------------------
  68. # Changes in the GUI should be read in when
  69. # running any process. Changing something here.
  70. # --------------------------------------------------
  71. form_field = excellon_obj.form_fields['feedrate']
  72. value = form_field.get_value()
  73. form_field.set_value(value * 1.1) # Increase by 10%
  74. print(("'feedrate' == {}".format(value)))
  75. # --------------------------------------------------
  76. # Create GCode using all tools.
  77. # --------------------------------------------------
  78. assert isinstance(excellon_obj, FlatCAMExcellon) # Just for the IDE
  79. ui = excellon_obj.ui
  80. assert isinstance(ui, ExcellonObjectUI)
  81. ui.tools_table.selectAll() # Select All
  82. ui.generate_cnc_button.click() # Click
  83. # Work is done in a separate thread and results are
  84. # passed via events to the main event loop which is
  85. # not running. Run only for pending events.
  86. #
  87. # I'm not sure why, but running it only once does
  88. # not catch the new object. Might be a timing issue.
  89. # http://pyqt.sourceforge.net/Docs/PyQt4/qeventloop.html#details
  90. for _ in range(2):
  91. sleep(0.1)
  92. self.app.processEvents()
  93. # ---------------------------------------------
  94. # Check that GUI has been read in.
  95. # ---------------------------------------------
  96. value = excellon_obj.options['feedrate']
  97. form_value = form_field.get_value()
  98. self.assertEqual(value, form_value,
  99. "Form value for '{}' == {} was not read into options"
  100. "which has {}".format('feedrate', form_value, value))
  101. print(("'feedrate' == {}".format(value)))
  102. # ---------------------------------------------
  103. # Check that only 1 object has been created.
  104. # ---------------------------------------------
  105. names = self.fc.collection.get_names()
  106. self.assertEqual(len(names), 2,
  107. "Expected 2 objects, found %d" % len(names))
  108. # -------------------------------------------------------
  109. # Make sure the CNCJob Object has the correct name
  110. # -------------------------------------------------------
  111. cncjob_name = excellon_name + "_cnc"
  112. self.assertTrue(cncjob_name in names,
  113. "Object named %s not found." % cncjob_name)
  114. # -------------------------------------------------------
  115. # Get the object make sure it's a cncjob object
  116. # -------------------------------------------------------
  117. cncjob_obj = self.fc.collection.get_by_name(cncjob_name)
  118. self.assertTrue(isinstance(cncjob_obj, FlatCAMCNCjob),
  119. "Expected a FlatCAMCNCjob, got %s" % type(cncjob_obj))
  120. # -----------------------------------------
  121. # Export G-Code, check output
  122. # -----------------------------------------
  123. assert isinstance(cncjob_obj, FlatCAMCNCjob) # For IDE
  124. # get system temporary file(try create it and delete)
  125. with tempfile.NamedTemporaryFile(prefix='unittest.',
  126. suffix="." + cncjob_name + '.gcode',
  127. delete=True) as tmp_file:
  128. output_filename = tmp_file.name
  129. cncjob_obj.export_gcode(output_filename)
  130. self.assertTrue(os.path.isfile(output_filename))
  131. os.remove(output_filename)
  132. print(names)