336 lines
14 KiB
Python
336 lines
14 KiB
Python
# -*- coding: utf-8 -*-
|
|
# ***************************************************************************
|
|
# * Copyright (c) 2024 Ondsel <development@ondsel.com> *
|
|
# * *
|
|
# * This program is free software; you can redistribute it and/or modify *
|
|
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
|
# * as published by the Free Software Foundation; either version 2 of *
|
|
# * the License, or (at your option) any later version. *
|
|
# * for detail see the LICENCE text file. *
|
|
# * *
|
|
# * This program is distributed in the hope that it will be useful, *
|
|
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
# * GNU Library General Public License for more details. *
|
|
# * *
|
|
# * You should have received a copy of the GNU Library General Public *
|
|
# * License along with this program; if not, write to the Free Software *
|
|
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
|
# * USA *
|
|
# * *
|
|
# ***************************************************************************
|
|
|
|
import FreeCAD
|
|
import Path
|
|
from Path.Main.Sanity import ReportGenerator, Sanity
|
|
from Path.Main.Sanity.ImageBuilder import (
|
|
DummyImageBuilder,
|
|
ImageBuilderFactory,
|
|
ImageBuilder,
|
|
)
|
|
import os
|
|
import Path.Post.Command as PathPost
|
|
from Path.Post.Processor import PostProcessor
|
|
import unittest
|
|
from unittest.mock import patch, MagicMock
|
|
import urllib
|
|
import tempfile
|
|
from CAMTests.PathTestUtils import PathTestBase
|
|
|
|
|
|
class TestCAMSanity(PathTestBase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
FreeCAD.ConfigSet("SuppressRecomputeRequiredDialog", "True")
|
|
cls.doc = FreeCAD.open(FreeCAD.getHomePath() + "/Mod/CAM/CAMTests/boxtest.fcstd")
|
|
FreeCAD.ConfigSet("SuppressRecomputeRequiredDialog", "")
|
|
cls.job = cls.doc.getObject("Job")
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
FreeCAD.closeDocument("boxtest")
|
|
|
|
def setUp(self):
|
|
self.temp_file = tempfile.NamedTemporaryFile()
|
|
|
|
def tearDown(self):
|
|
pass
|
|
|
|
def test00(self):
|
|
"""Test no output location"""
|
|
with self.assertRaises(TypeError):
|
|
S = Sanity.CAMSanity(self.job)
|
|
|
|
def test010(self):
|
|
# """Test CAMSanity using a DummyImageBuilder"""
|
|
with patch(
|
|
"Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder"
|
|
) as mock_factory:
|
|
dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
mock_factory.return_value = dummy_builder
|
|
S = Sanity.CAMSanity(self.job, output_file=self.temp_file.name)
|
|
self.assertTrue(os.path.isdir(S.filelocation))
|
|
self.assertEqual(self.temp_file.name, S.output_file)
|
|
|
|
def test020(self):
|
|
"""Test erroneous output location"""
|
|
filename = "/tmpXXXX/THIS_DOESN'T_EXIST"
|
|
with self.assertRaises(ValueError):
|
|
S = Sanity.CAMSanity(self.job, output_file=filename)
|
|
|
|
# This test fails A headless image generation routine is needed.
|
|
# def test40(self):
|
|
# """Test image generation"""
|
|
# import imghdr # fixme: not available in python3.13
|
|
# path = FreeCAD.getUserMacroDir()
|
|
# image_builder = ImageBuilder.ImageBuilderFactory.get_image_builder(path)
|
|
# file_name = image_builder.build_image(self.doc.getObject("Box"), "theBox")
|
|
# print(f"filename:{file_name}")
|
|
|
|
# # This test shouldn't be enabled in production as is.
|
|
# # it writes to the user macro directory as a persistent location.
|
|
# # writing to tempdir fails
|
|
# # the tempfile get cleaned up before we can do any asserts.
|
|
|
|
# # Need to find a way to write semi-persistently for the tests to pass
|
|
|
|
# with open(file_name, 'rb') as f:
|
|
# header = f.read(32) # Read the first 32 bytes
|
|
# self.assertTrue(imghdr.what(None, header) is not None)
|
|
|
|
def test050(self):
|
|
"""Test base data"""
|
|
with patch(
|
|
"Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder"
|
|
) as mock_factory:
|
|
dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
mock_factory.return_value = dummy_builder
|
|
S = Sanity.CAMSanity(self.job, output_file=self.temp_file.name)
|
|
data = S._baseObjectData()
|
|
self.assertIsInstance(data, dict)
|
|
self.assertIn("baseimage", data)
|
|
self.assertIn("bases", data)
|
|
|
|
def test060(self):
|
|
"""Test design data"""
|
|
with patch(
|
|
"Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder"
|
|
) as mock_factory:
|
|
dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
mock_factory.return_value = dummy_builder
|
|
S = Sanity.CAMSanity(self.job, output_file=self.temp_file.name)
|
|
data = S._designData()
|
|
self.assertIsInstance(data, dict)
|
|
self.assertIn("FileName", data)
|
|
self.assertIn("LastModifiedDate", data)
|
|
self.assertIn("Customer", data)
|
|
self.assertIn("Designer", data)
|
|
self.assertIn("JobDescription", data)
|
|
self.assertIn("JobLabel", data)
|
|
self.assertIn("Sequence", data)
|
|
self.assertIn("JobType", data)
|
|
|
|
def test070(self):
|
|
"""Test tool data"""
|
|
with patch(
|
|
"Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder"
|
|
) as mock_factory:
|
|
dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
mock_factory.return_value = dummy_builder
|
|
S = Sanity.CAMSanity(self.job, output_file=self.temp_file.name)
|
|
data = S._toolData()
|
|
self.assertIn("squawkData", data)
|
|
|
|
for key in data.keys():
|
|
if isinstance(key, int):
|
|
val = data["key"]
|
|
self.assertIsInstance(val, dict)
|
|
self.assertIn("bitShape", val)
|
|
self.assertIn("description", val)
|
|
self.assertIn("manufacturer", val)
|
|
self.assertIn("url", val)
|
|
self.assertIn("inspectionNotes", val)
|
|
self.assertIn("diameter", val)
|
|
self.assertIn("shape", val)
|
|
self.assertIn("partNumber", val)
|
|
|
|
def test080(self):
|
|
"""Test run data"""
|
|
with patch(
|
|
"Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder"
|
|
) as mock_factory:
|
|
dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
mock_factory.return_value = dummy_builder
|
|
S = Sanity.CAMSanity(self.job, output_file=self.temp_file.name)
|
|
data = S._runData()
|
|
self.assertIsInstance(data, dict)
|
|
self.assertIn("cycletotal", data)
|
|
self.assertIn("jobMinZ", data)
|
|
self.assertIn("jobMaxZ", data)
|
|
self.assertIn("jobDescription", data)
|
|
self.assertIn("squawkData", data)
|
|
self.assertIn("operations", data)
|
|
|
|
def test090(self):
|
|
"""Test output data"""
|
|
with patch(
|
|
"Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder"
|
|
) as mock_factory:
|
|
dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
mock_factory.return_value = dummy_builder
|
|
S = Sanity.CAMSanity(self.job, output_file=self.temp_file.name)
|
|
data = S._outputData()
|
|
self.assertIsInstance(data, dict)
|
|
self.assertIn("lastpostprocess", data)
|
|
self.assertIn("lastgcodefile", data)
|
|
self.assertIn("optionalstops", data)
|
|
self.assertIn("programmer", data)
|
|
self.assertIn("machine", data)
|
|
self.assertIn("postprocessor", data)
|
|
self.assertIn("postprocessorFlags", data)
|
|
self.assertIn("filesize", data)
|
|
self.assertIn("linecount", data)
|
|
self.assertIn("outputfilename", data)
|
|
self.assertIn("squawkData", data)
|
|
|
|
def test100(self):
|
|
"""Test fixture data"""
|
|
with patch(
|
|
"Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder"
|
|
) as mock_factory:
|
|
dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
mock_factory.return_value = dummy_builder
|
|
S = Sanity.CAMSanity(self.job, output_file=self.temp_file.name)
|
|
data = S._fixtureData()
|
|
self.assertIsInstance(data, dict)
|
|
self.assertIn("fixtures", data)
|
|
self.assertIn("orderBy", data)
|
|
self.assertIn("datumImage", data)
|
|
self.assertIn("squawkData", data)
|
|
|
|
def test110(self):
|
|
"""Test stock data"""
|
|
with patch(
|
|
"Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder"
|
|
) as mock_factory:
|
|
dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
mock_factory.return_value = dummy_builder
|
|
S = Sanity.CAMSanity(self.job, output_file=self.temp_file.name)
|
|
data = S._stockData()
|
|
self.assertIsInstance(data, dict)
|
|
self.assertIn("xLen", data)
|
|
self.assertIn("yLen", data)
|
|
self.assertIn("zLen", data)
|
|
self.assertIn("material", data)
|
|
self.assertIn("stockImage", data)
|
|
self.assertIn("squawkData", data)
|
|
|
|
def test120(self):
|
|
"""Test squawk data"""
|
|
with patch(
|
|
"Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder"
|
|
) as mock_factory:
|
|
dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
mock_factory.return_value = dummy_builder
|
|
S = Sanity.CAMSanity(self.job, output_file=self.temp_file.name)
|
|
data = S.squawk(
|
|
"CAMSanity",
|
|
"Test Message",
|
|
squawkType="TIP",
|
|
)
|
|
self.assertIsInstance(data, dict)
|
|
self.assertIn("Date", data)
|
|
self.assertIn("Operator", data)
|
|
self.assertIn("Note", data)
|
|
self.assertIn("squawkType", data)
|
|
self.assertIn("squawkIcon", data)
|
|
|
|
def test130(self):
|
|
"""Test tool data"""
|
|
with patch(
|
|
"Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder"
|
|
) as mock_factory:
|
|
dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
mock_factory.return_value = dummy_builder
|
|
S = Sanity.CAMSanity(self.job, output_file=self.temp_file.name)
|
|
data = S._toolData()
|
|
self.assertIsInstance(data, dict)
|
|
self.assertIn("squawkData", data)
|
|
|
|
for key, val in data.items():
|
|
if key == "squawkData":
|
|
continue
|
|
else:
|
|
self.assertIsInstance(val, dict)
|
|
self.assertIn("bitShape", val)
|
|
self.assertIn("description", val)
|
|
self.assertIn("manufacturer", val)
|
|
self.assertIn("url", val)
|
|
self.assertIn("inspectionNotes", val)
|
|
self.assertIn("diameter", val)
|
|
self.assertIn("shape", val)
|
|
self.assertIn("partNumber", val)
|
|
|
|
# def test140(self):
|
|
# """Test Generate Report"""
|
|
# with patch('Path.Main.Sanity.ImageBuilder.ImageBuilderFactory.get_image_builder') as mock_factory:
|
|
# dummy_builder = DummyImageBuilder(self.temp_file.name)
|
|
# mock_factory.return_value = dummy_builder
|
|
# S = Sanity.CAMSanity(self.job, output_file= self.temp_file.name)
|
|
# html_content = S.get_output_report()
|
|
# self.assertIsInstance(html_content, str)
|
|
|
|
# def test150(self):
|
|
# """Test Post Processing a File"""
|
|
|
|
# def exportObjectsWith(objs, partname, job, sequence, postname):
|
|
# Path.Log.track(partname, sequence)
|
|
# Path.Log.track(objs)
|
|
|
|
# Path.Log.track(objs, partname)
|
|
|
|
# postArgs = Path.Preferences.defaultPostProcessorArgs()
|
|
# if hasattr(job, "PostProcessorArgs") and job.PostProcessorArgs:
|
|
# postArgs = job.PostProcessorArgs
|
|
# elif hasattr(job, "PostProcessor") and job.PostProcessor:
|
|
# postArgs = ""
|
|
|
|
# Path.Log.track(postArgs)
|
|
|
|
# filename = f"output-{partname}-{sequence}.ngc"
|
|
|
|
# processor = PostProcessor.load(postname)
|
|
# gcode = processor.export(objs, filename, postArgs)
|
|
# return (gcode, filename)
|
|
|
|
# doc = FreeCAD.open(FreeCAD.getHomePath() + "/Mod/CAM/CAMTests/boxtest.fcstd")
|
|
# job = self.doc.getObject("Job")
|
|
|
|
# postlist = PathPost.buildPostList(job)
|
|
|
|
# filenames = []
|
|
# for idx, section in enumerate(postlist):
|
|
# partname = section[0]
|
|
# sublist = section[1]
|
|
|
|
# gcode, name = exportObjectsWith(sublist, partname, job, idx, "linuxcnc")
|
|
# filenames.append(name)
|
|
|
|
# with tempfile.TemporaryDirectory() as temp_dir:
|
|
# output_file_path = temp_dir
|
|
|
|
# output_file_name = os.path.join(output_file_path, "test.ngc")
|
|
|
|
# def test200(self):
|
|
# """Generate Report This test is disabled but useful during development to see the report"""
|
|
# with tempfile.NamedTemporaryFile() as temp_file:
|
|
# S= Sanity.CAMSanity(self.job, output_file=temp_file.name)
|
|
# shape = self.doc.getObject("Box")
|
|
# html_content = S.get_output_report()
|
|
|
|
# encoded_html = urllib.parse.quote(html_content)
|
|
|
|
# data_uri = f"data:text/html;charset=utf-8,{encoded_html}"
|
|
# import webbrowser
|
|
# webbrowser.open(data_uri)
|