def test_planArc_counterClockwise_semicircle(self):
        """Tests the planArc method with a CCW semicircular 100 unit arc centered at (0,0)."""
        arcRadius = 50

        mockLogger = mock.Mock()

        mockState = mock.Mock()
        mockState.position.X_AXIS.nativeToLogical.return_value = -arcRadius
        mockState.position.Y_AXIS.nativeToLogical.return_value = 0

        unit = GcodeHandlers(mockState, mockLogger)

        result = unit.planArc(arcRadius, 0, arcRadius, 0, False)

        self._assert_planArc_commonResultProperties(start=(-arcRadius, 0),
                                                    end=(arcRadius, 0),
                                                    center=(0, 0),
                                                    radius=arcRadius,
                                                    items=result)

        # y value comparisons
        # - the y component of each point should be below or equal to the y axis
        # - the y component direction must change one time
        self._assert_planArc_axisProperties(
            coordinateOffset=1,
            initialValue=0,
            initialDirection=-1,
            expectedReversals=1,
            items=result,
            filterFunc=lambda x, y, direction, index: (self.assertTrue(
                y <= 0, "Each y coordinate should be on or below the Y axis" +
                ": pt=(%s, %s) index=%s" % (x, y, index))))

        # x value comparisons
        # - the x component of each point should increase for each point
        self._assert_planArc_axisProperties(coordinateOffset=0,
                                            initialValue=-arcRadius,
                                            initialDirection=1,
                                            expectedReversals=0,
                                            items=result)
    def test_planArc_counterClockwise_circle(self):
        """Tests the planArc method with a CCW circular 100 unit arc centered at (0,0)."""
        arcRadius = 50

        mockLogger = mock.Mock()

        mockState = mock.Mock()
        mockState.position.X_AXIS.nativeToLogical.return_value = -arcRadius
        mockState.position.Y_AXIS.nativeToLogical.return_value = 0

        unit = GcodeHandlers(mockState, mockLogger)

        result = unit.planArc(-arcRadius, 0, arcRadius, 0, False)

        self._assert_planArc_commonResultProperties(start=(-arcRadius, 0),
                                                    end=(-arcRadius, 0),
                                                    center=(0, 0),
                                                    radius=arcRadius,
                                                    items=result)

        # y value comparisons
        # - the y component of each point to the left of x axis should have a negative direction
        # - the y component of each point to the right of x axis should have a positive direction
        # - the y component direction must change two times
        ignoredY = {"first": False}

        def filter_y(x, y, direction, index):
            if (x < 0):
                self.assertEqual(
                    direction, -1,
                    "The y direction should be negative for points to the left of the x axis"
                    + ": pt=(%s, %s) index=%s" % (x, y, index))
            elif (ignoredY["first"]):
                self.assertEqual(
                    direction, 1,
                    "The y direction should be positive for points to the right of the x axis"
                    + ": pt=(%s, %s) index=%s" % (x, y, index))
            else:
                # Ignore the first one, since it _could_ have the opposite direction at the boundary
                ignoredY["first"] = True

        self._assert_planArc_axisProperties(coordinateOffset=1,
                                            initialValue=0,
                                            initialDirection=-1,
                                            expectedReversals=2,
                                            items=result,
                                            filterFunc=filter_y)

        # x value comparisons
        # - the x component of each point above the y axis should have a negative direction
        # - the x component of each point below the y axis should have a positive direction
        # - the x component direction must change one time
        ignoredX = {"first": False}

        def filter_x(x, y, direction, index):
            if (y < 0):
                self.assertEqual(
                    direction, 1,
                    "The x direction should be positive for points below the y axis"
                    + ": pt=(%s, %s) index=%s" % (x, y, index))
            elif (ignoredX["first"]):
                self.assertEqual(
                    direction, -1,
                    "The x direction should be negative for points above the y axis"
                    + ": pt=(%s, %s) index=%s" % (x, y, index))
            else:
                # Ignore the first one, since it _could_ have the opposite direction at the boundary
                ignoredX["first"] = True

        self._assert_planArc_axisProperties(coordinateOffset=0,
                                            initialValue=-arcRadius,
                                            initialDirection=1,
                                            expectedReversals=1,
                                            items=result,
                                            filterFunc=filter_x)