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")
    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_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_processExtendedGcodeEntry_EXCLUDE_MERGE_noPendingArgs_noCmdArgs(
            self):
        """Test processExtendedGcodeEntry / EXCLUDE_MERGE if no pending args and no command args."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        unit.pendingCommands = OrderedDict()

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

        self.assertEqual(unit.pendingCommands, OrderedDict([("G1", {})]),
                         "pendingCommands should be updated.")
        self.assertEqual(
            result, (None, ),
            "The result should indicate to drop/ignore the command")
    def test_processExtendedGcodeEntry_EXCLUDE_EXCEPT_LAST_notYetSeen(self):
        """Test processExtendedGcodeEntry / EXCLUDE_EXCEPT_LAST for a Gcode not yet seen."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        unit.pendingCommands = OrderedDict([("M117", "M117 Test")])

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

        # Command should be appended to end of pendingCommands
        self.assertEqual(
            unit.pendingCommands,
            OrderedDict([("M117", "M117 Test"), ("G1", "G1 X1 Y2")]),
            "pendingCommands should be updated with new command string.")
        self.assertEqual(
            result, (None, ),
            "The result should indicate to drop/ignore the command")
    def test_processExtendedGcodeEntry_EXCLUDE_EXCEPT_FIRST_alreadySeen(self):
        """Test processExtendedGcodeEntry / EXCLUDE_EXCEPT_FIRST for a Gcode already seen."""
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)
        unit.pendingCommands = OrderedDict([("G1", "G1 E3 Z4"),
                                            ("M117", "M117 Test")])

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

        # Previous command entry should not be affected
        self.assertEqual(
            unit.pendingCommands,
            OrderedDict([("G1", "G1 E3 Z4"), ("M117", "M117 Test")]),
            "pendingCommands should not be updated.")
        self.assertEqual(
            result, (None, ),
            "The result should indicate to drop/ignore the command")
    def _resetStateSetup():
        """Create and initialize the instance to test the resetState method on."""
        # pylint: disable=protected-access
        mockLogger = mock.Mock()
        unit = ExcludeRegionState(mockLogger)

        unit.excludedRegions = ["abc"]
        unit.position.X_AXIS.current = 100
        unit.feedRate = 100
        unit.feedRateUnitMultiplier = 1234
        unit._exclusionEnabled = False
        unit.excluding = True
        unit.excludeStartTime = None
        unit.numExcludedCommands = 4321
        unit.numCommands = 6789
        unit.lastRetraction = "abc"
        unit.lastPosition = "123"
        unit.pendingCommands = {"a": 1}

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

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

        # Order of elements should be updated
        self.assertEqual(
            unit.pendingCommands,
            OrderedDict([("M117", "M117 Test"), ("G1", {
                "X": 10
            })]),
            "pendingCommands should be updated with new argument values.")
        self.assertEqual(
            result, (None, ),
            "The result should indicate to drop/ignore the command")