def test_processExtendedGcodeEntry_EXCLUDE_MERGE_hasPendingArgs_cmdHasArgs(
            self):
        """Test processExtendedGcodeEntry / EXCLUDE_MERGE if pending args and command with args."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        unit.pendingCommands = OrderedDict([("G1", {
            "X": 10,
            "Z": 20
        }), ("M117", "M117 Test")])

        # Use upper and lower case args to test case-sensitivity
        result = unit._processExtendedGcodeEntry(  # pylint: disable=protected-access
            EXCLUDE_MERGE, "G1 x1 Y2", "G1")

        # Order of elements and parameter values should be updated
        self.assertEqual(
            unit.pendingCommands,
            OrderedDict([("M117", "M117 Test"),
                         ("G1", {
                             "X": 1,
                             "Y": 2,
                             "Z": 20
                         })]),
            "pendingCommands should be updated with new argument values.")
        self.assertEqual(
            result, (None, ),
            "The result should indicate to drop/ignore the command")
Exemplo n.º 2
0
    def test_recoverRetractionIfNeeded_lastRetraction_notExcluding(self):
        """Test recoverRetractionIfNeeded with a lastRetraction and NOT excluding."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        with mock.patch.multiple(unit,
                                 _recoverRetraction=mock.DEFAULT,
                                 lastRetraction=mock.DEFAULT) as mocks:
            unit.excluding = False
            unit.lastRetraction.recoverExcluded = False
            unit.lastRetraction.allowCombine = True
            mocks["_recoverRetraction"].return_value = ["expectedCommand"]

            result = unit.recoverRetractionIfNeeded("G11", True)

            mocks["_recoverRetraction"].assert_called_with("G11", True)
            self.assertEqual(unit.lastRetraction, mocks["lastRetraction"],
                             "The lastRetraction should not be updated")
            self.assertFalse(unit.lastRetraction.allowCombine,
                             "allowCombine should be set to False")
            self.assertFalse(unit.lastRetraction.recoverExcluded,
                             "recoverExcluded should not be updated")
            self.assertEqual(
                result, ["expectedCommand"],
                "The result should match the list of commands returned by _recoverRetraction"
            )
    def test_isExclusionEnabled_enabled(self):
        """Test the isExclusionEnabled method when exclusion is enabled."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        self.assertTrue(unit.isExclusionEnabled(),
                        "isExclusionEnabled should report True")
    def test_replaceRegion_found_middle(self):
        """Test the replaceRegion method when the matched region not first nor last in the list."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        firstRegion = RectangularRegion(x1=20,
                                        y1=20,
                                        x2=30,
                                        y2=30,
                                        id="firstId")
        regionToMatch = RectangularRegion(x1=10,
                                          y1=10,
                                          x2=20,
                                          y2=20,
                                          id="matchId")
        lastRegion = RectangularRegion(x1=30, y1=30, x2=40, y2=40, id="lastId")
        newRegion = RectangularRegion(x1=0, y1=0, x2=100, y2=100, id="matchId")

        unit.addRegion(firstRegion)
        unit.addRegion(regionToMatch)
        unit.addRegion(lastRegion)

        unit.replaceRegion(newRegion)

        self.assertEqual(
            unit.excludedRegions, [firstRegion, newRegion, lastRegion],
            "The excluded regions should be updated by replaceRegion if the ID is found (last)"
        )
    def test_recordRetraction_recoverExcluded_firmwareRetract(self):
        """Test recordRetraction with recoverExcluded=True and a firmware retract."""
        mockRetractionState = mock.Mock()
        mockRetractionState.originalCommand = "retractionCommand"

        mockLogger = mock.Mock()

        unit = ExcludeRegionState(mockLogger)
        with mock.patch.object(unit, 'lastRetraction'):
            unit.feedRate = 20
            unit.lastRetraction.recoverExcluded = True
            unit.lastRetraction.firmwareRetract = True
            unit.lastRetraction.feedRate = None

            returnCommands = unit.recordRetraction(mockRetractionState)

            self.assertFalse(
                unit.lastRetraction.recoverExcluded,
                "lastRetraction.recoverExcluded should be set to False")

            self.assertIsNone(
                unit.lastRetraction.feedRate,
                "The retraction feedRate should not be modified.")

            self.assertEqual(returnCommands, [],
                             "The result should be an empty list.")
Exemplo n.º 6
0
    def test_recoverRetractionIfNeeded_lastRetraction_excluding_notRecoveryCommand(
            self):
        """Test recoverRetractionIfNeeded with lastRetraction, excluding and NO recoveryCommand."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        with mock.patch.multiple(unit,
                                 _recoverRetraction=mock.DEFAULT,
                                 lastRetraction=mock.DEFAULT) as mocks:
            unit.excluding = True
            unit.lastRetraction.recoverExcluded = False
            unit.lastRetraction.allowCombine = True

            result = unit.recoverRetractionIfNeeded("G1 X1 Y2 E3", False)

            # The test against this mock covers both cases where returnCommands None and when it is
            # a list of commands since the final result is built from the _recoverRetraction result
            # which is mocked anyway
            mocks["_recoverRetraction"].assert_not_called()
            self.assertEqual(unit.lastRetraction, mocks["lastRetraction"],
                             "The lastRetraction should not be updated")
            self.assertFalse(unit.lastRetraction.allowCombine,
                             "allowCombine should be set to False")
            self.assertFalse(unit.lastRetraction.recoverExcluded,
                             "recoverExcluded should not be updated")
            self.assertEqual(result, [], "The result should be an empty list.")
    def test_getRegion_notExists(self):
        """Test the getRegion method when no such region is defined."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        self.assertIsNone(
            unit.getRegion("someId"),
            "getRegion return None when the region isn't defined")
    def test_isExclusionEnabled_disabled(self):
        """Test the isExclusionEnabled method when exclusion is disabled."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        unit.disableExclusion("Disable for test")

        self.assertFalse(unit.isExclusionEnabled(),
                         "isExclusionEnabled should report False")
    def test_isAnyPointExcluded_lastExcluded(self):
        """Test the isAnyPointExcluded method when only the last point is excluded."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        aRegion = RectangularRegion(x1=0, y1=0, x2=5, y2=5)
        unit.addRegion(aRegion)

        self.assertTrue(unit.isAnyPointExcluded(10, 10, 0, 0),
                        "(0,0) should be excluded (last)")
    def test_deleteRegion_noRegions(self):
        """Test the deleteRegion method when no regions are defined."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        self.assertFalse(
            unit.deleteRegion("notFound"),
            "deleteRegion should return False when the region is not found (no regions defined)"
        )
    def test_replaceRegion_noRegions(self):
        """Test the replaceRegion method when no regions are defined."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        newRegion = RectangularRegion(x1=0, y1=0, x2=100, y2=100, id="someId")

        with self.assertRaises(ValueError):
            unit.replaceRegion(newRegion)
    def test_isAnyPointExcluded_middleExcluded(self):
        """Test the isAnyPointExcluded method a point other than the first or last is excluded."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        aRegion = RectangularRegion(x1=0, y1=0, x2=5, y2=5)
        unit.addRegion(aRegion)

        self.assertTrue(unit.isAnyPointExcluded(10, 10, 0, 0, 20, 20),
                        "(0,0) should be excluded (middle)")
    def test_isAnyPointExcluded_noArguments(self):
        """Test the isAnyPointExcluded method when no arguments are provided."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        aRegion = RectangularRegion(x1=0, y1=0, x2=5, y2=5)
        unit.addRegion(aRegion)

        self.assertFalse(
            unit.isAnyPointExcluded(),
            "isAnyPointExcluded should return false when passed no arguments")
    def test_replaceRegion_missingId(self):
        """Test the replaceRegion method when the region procided doesn't have an assigned ID."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        newRegion = RectangularRegion(x1=0, y1=0, x2=100, y2=100)
        newRegion.id = None

        with self.assertRaises(ValueError):
            unit.replaceRegion(newRegion)
    def test_exitExcludedRegion_zIncreased(self):
        """Test exitExcludedRegion when the final Z is greater than the initial Z."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        unit.excluding = True
        unit.excludeStartTime = time.time()
        unit.feedRate = 1000
        unit.feedRateUnitMultiplier = 1
        unit.lastPosition = create_position(x=1, y=2, z=3, extruderPosition=4)
        unit.position = create_position(x=10, y=20, z=30, extruderPosition=40)

        with mock.patch.object(
                unit, '_processPendingCommands') as mockProcessPendingCommands:
            mockProcessPendingCommands.return_value = ["pendingCommand"]

            result = unit.exitExcludedRegion("G1 X1 Y2")

            mockProcessPendingCommands.assert_called_with()
            self.assertEqual(
                result, [
                    "pendingCommand", "G92 E40", "G0 F1000 Z30",
                    "G0 F1000 X10 Y20"
                ], "The result should be a list of the expected commands.")
            self.assertFalse(unit.excluding,
                             "The excluding flag should be cleared.")
    def _test_enterExcludedRegion_common(self, enteringExcludedRegionGcode):
        """Test common functionality of enterExcludedRegion when exclusion is enabled."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        unit.excluding = False
        unit.excludeStartTime = "oldStartTime"
        unit.numExcludedCommands = 42
        unit.numCommands = 84
        unit.lastPosition = "oldPosition"

        unit.enteringExcludedRegionGcode = enteringExcludedRegionGcode

        result = unit.enterExcludedRegion("G1 X1 Y2")

        self.assertTrue(unit.excluding, "The excluding flag should be True")
        self.assertNotEqual(unit.excludeStartTime, "oldStartTime",
                            "The excludeStartTime should be updated")
        self.assertEqual(unit.numExcludedCommands, 0,
                         "The numExcludedCommands should be reset to 0")
        self.assertEqual(unit.numCommands, 0,
                         "The numCommands should be reset to 0")
        self.assertNotEqual(unit.lastPosition, "oldPosition",
                            "The position should be updated")

        return result
    def test_isPointExcluded_noRegions(self):
        """Test the isPointExcluded method when no regions are defined."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        self.assertFalse(
            unit.isPointExcluded(0, 0),
            "(0,0) should NOT be excluded when no regions are defined")
        self.assertFalse(
            unit.isPointExcluded(10, 10),
            "(10,10) should NOT be excluded when no regions are defined")
    def test_setAbsoluteMode_False_g90InfluencesExtruder(self):
        """Test the setAbsoluteMode method when passed False and g90InfluencesExtruder is True."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        unit.g90InfluencesExtruder = True
        unit.position.setPositionAbsoluteMode(True)
        unit.position.setExtruderAbsoluteMode(True)

        unit.setAbsoluteMode(False)

        self._assertAbsoluteMode(unit, False, False)
    def test_enableExclusion_exclusionEnabled(self):
        """Test the enableExclusion method when exclusion is already enabled."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        unit.enableExclusion("Redundant enable for test")

        mockLogger.debug.assert_called_with(
            RegexMatcher("^Exclusion already enabled"), mock.ANY)
        self.assertTrue(unit.isExclusionEnabled(),
                        "isExclusionEnabled should report True")
    def test_processPendingCommands_noPendingCommands_noExitScript(self):
        """Test _processPendingCommands if no pending commands and no exit script."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        unit.pendingCommands = OrderedDict()
        unit.exitingExcludedRegionGcode = None

        result = unit._processPendingCommands()  # pylint: disable=protected-access

        self.assertEqual(unit.pendingCommands, OrderedDict(),
                         "The pendingCommands should be an empty dict")
        self.assertEqual(result, [], "The result should be an empty list.")
    def test_processExtendedGcode_noGcode_notExcluding(self):
        """Test processExtendedGcode when not excluding and no gcode provided."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        with mock.patch.object(
                unit, 'extendedExcludeGcodes') as mockExtendedExcludeGcodes:
            unit.excluding = False

            result = unit.processExtendedGcode("someCommand", None, None)

            mockExtendedExcludeGcodes.get.assert_not_called()
            self.assertIsNone(result, "The return value should be None")
    def test_exitExcludedRegion_excluding(self):
        """Test exitExcludedRegion when already excluding."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        unit.excluding = True
        unit.numCommands = 10

        result = unit.enterExcludedRegion("G1 X1 Y2")

        self.assertEqual(unit.numCommands, 10,
                         "The numCommands should not be updated.")
        self.assertEqual(result, [], "An empty list should be returned.")
    def test_exitExcludedRegion_notExcluding(self):
        """Test exitExcludedRegion when not currently excluding."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        unit.excluding = False

        with mock.patch.object(
                unit, '_processPendingCommands') as mockProcessPendingCommands:
            result = unit.exitExcludedRegion("G1 X1 Y2")

            mockProcessPendingCommands.assert_not_called()
            self.assertEqual(result, [], "An empty list should be returned.")
    def test_ignoreGcodeCommand(self):
        """Test the ignoreGcodeCommand method."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        unit.numExcludedCommands = 10

        result = unit.ignoreGcodeCommand()

        self.assertEqual(result, IGNORE_GCODE_CMD,
                         "ignoreGcodeCommand should return IGNORE_GCODE_CMD")
        self.assertEqual(
            unit.numExcludedCommands, 11,
            "ignoreGcodeCommand should increment numExcludedCommands")
    def test_disableExclusion_exclusionEnabled_notExcluding(
            self, mockExitExcludedRegion):
        """Test the disableExclusion method when exclusion is enabled and not excluding."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        returnedCommands = unit.disableExclusion("Disable for test")

        self.assertFalse(unit.isExclusionEnabled(),
                         "isExclusionEnabled should report False")
        mockExitExcludedRegion.assert_not_called()
        self.assertEqual(returnedCommands, [],
                         "An empty list of commands should be returned")
Exemplo n.º 26
0
    def test_processExcludedMove_excluding_nonRetract(self):
        """Test _processExcludedMove with a non-retraction move and excluding=True."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        unit.excluding = True

        with mock.patch.multiple(unit,
                                 enterExcludedRegion=mock.DEFAULT,
                                 _processNonMove=mock.DEFAULT) as mocks:
            result = unit._processExcludedMove("G1 X10 Y20", 0)  # pylint: disable=protected-access

            mocks["enterExcludedRegion"].assert_not_called()
            mocks["_processNonMove"].assert_not_called()
            self.assertEqual(result, [], "The result should be an empty list")
    def test_processExtendedGcodeEntry_EXCLUDE_ALL(self):
        """Test processExtendedGcodeEntry when the mode is EXCLUDE_ALL."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        unit.pendingCommands = OrderedDict()

        result = unit._processExtendedGcodeEntry(  # pylint: disable=protected-access
            EXCLUDE_ALL, "G1 X1 Y2", "G1")

        self.assertEqual(unit.pendingCommands, OrderedDict(),
                         "pendingCommands should not be updated.")
        self.assertEqual(
            result, (None, ),
            "The result should indicate to drop/ignore the command")
    def test_recoverRetraction_noRecoverExcluded(self):
        """Test _recoverRetraction with recoverExcluded=False."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        with mock.patch.object(unit, 'lastRetraction') as lastRetractionMock:
            unit.lastRetraction.recoverExcluded = False

            result = unit._recoverRetraction("G11", True)  # pylint: disable=protected-access

            lastRetractionMock.generateRecoverCommands.assert_not_called()
            self.assertIsNone(unit.lastRetraction,
                              "The lastRetraction should be set to None")
            self.assertEqual(result, ["G11"],
                             "The result should contain one item")
    def test_replaceRegion_found_last(self):
        """Test the replaceRegion method when the region matches the last in the list."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        regionToMatch = RectangularRegion(x1=10,
                                          y1=10,
                                          x2=20,
                                          y2=20,
                                          id="matchId")
        otherRegion = RectangularRegion(x1=20,
                                        y1=20,
                                        x2=30,
                                        y2=30,
                                        id="otherId")
        newRegion = RectangularRegion(x1=0, y1=0, x2=100, y2=100, id="matchId")

        unit.addRegion(otherRegion)
        unit.addRegion(regionToMatch)

        unit.replaceRegion(newRegion)

        self.assertEqual(
            unit.excludedRegions, [otherRegion, newRegion],
            "The excluded regions should be updated by replaceRegion if the ID is found (last)"
        )
    def test_deleteRegion_notFound(self):
        """Test the deleteRegion method when the specified region is not found."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        aRegion = RectangularRegion(x1=0, y1=0, x2=100, y2=100, id="anId")
        unit.addRegion(aRegion)

        self.assertFalse(
            unit.deleteRegion("notFound"),
            "deleteRegion should return False when the region is not found")
        self.assertEqual(
            unit.excludedRegions, [aRegion],
            "The excluded regions should not be modified by deleteRegion if the ID was not found"
        )