public void Test_Stability_DEC_Conversions()
        {
            // Specific test under one degree for positive and negative values of mechanical position
            {
                MechanicalPoint mp = new MechanicalPoint(0, -0.87);
                Assert.AreEqual(-0.87, mp.DECm);
                String s = "";
                Assert.AreEqual("-000:52:12", mp.toStringDEC(ref s));
                Assert.AreEqual("-00:52:12", mp.toStringDEC_Sim(ref s));
            }
            {
                MechanicalPoint mp = new MechanicalPoint(0, +0.87);
                Assert.AreEqual(+0.87, mp.DECm);
                String s = "";
                Assert.AreEqual("+000:52:12", mp.toStringDEC(ref s));
                Assert.AreEqual("+00:52:12", mp.toStringDEC_Sim(ref s));
            }

            // Doesn't test outside of -90,+90 but another test does roughly
            MechanicalPoint.PointingStates[] sides = { MechanicalPoint.PointingStates.POINTING_NORMAL, MechanicalPoint.PointingStates.POINTING_BEYOND_POLE };
            for (int ps = 0; ps < sides.Length; ps++)
            {
                for (int s = 0; s < 60; s++)
                {
                    for (int m = 0; m < 60; m++)
                    {
                        for (int d = -89; d <= +89; d++)
                        {
                            // Locals are on purpose - reset test material on each loop
                            MechanicalPoint p = new MechanicalPoint();
                            String          b = "", c = "";

                            p.PointingState = sides[ps];

                            b = $"{d:+00;-00;+00}:{m:00}:{s:00}";
                            p.parseStringDEC(b);
                            p.toStringDEC(ref c);

                            // Debug test with this block
                            if (b != c[0] + c.Substring(2))
                            {
                                p.parseStringDEC(b);
                                p.toStringDEC(ref c);
                            }

                            Assert.AreEqual(b, c[0] + c.Substring(2));

                            Assert.IsTrue(0 <= p.RAm && p.RAm <= +24);
                            Assert.IsTrue(-256 <= p.DECm && p.DECm <= 256);
                        }
                    }
                }
            }
        }
        public void Test_PierFlip()
        {
            MechanicalPoint p = new MechanicalPoint();
            String          b = "";

            // Mechanical point doesn't care about LST as it assumes the mount
            // is properly synced already. It only considers the pointing state.

            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState = MechanicalPoint.PointingStates.POINTING_BEYOND_POLE);
            Assert.AreEqual(0.0, p.RAsky    = +0.0);
            Assert.AreEqual(+90.0, p.DECsky = +90.0);
            Assert.AreEqual("12:00:00", p.toStringRA(ref b));
            Assert.AreEqual("+000:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState = MechanicalPoint.PointingStates.POINTING_NORMAL);
            Assert.AreEqual(0.0, p.RAsky    = +0.0);
            Assert.AreEqual(+90.0, p.DECsky = +90.0);
            Assert.AreEqual("00:00:00", p.toStringRA(ref b));
            Assert.AreEqual("+000:00:00", p.toStringDEC(ref b));

            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState = MechanicalPoint.PointingStates.POINTING_BEYOND_POLE);
            Assert.AreEqual(0.0, p.RAsky    = +0.0);
            Assert.AreEqual(+80.0, p.DECsky = +80.0);
            Assert.AreEqual("12:00:00", p.toStringRA(ref b));
            Assert.AreEqual("-010:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState = MechanicalPoint.PointingStates.POINTING_NORMAL);
            Assert.AreEqual(0.0, p.RAsky    = +0.0);
            Assert.AreEqual(+80.0, p.DECsky = +80.0);
            Assert.AreEqual("00:00:00", p.toStringRA(ref b));
            Assert.AreEqual("+010:00:00", p.toStringDEC(ref b));

            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState = MechanicalPoint.PointingStates.POINTING_BEYOND_POLE);
            Assert.AreEqual(0.0, p.RAsky    = +0.0);
            Assert.AreEqual(+70.0, p.DECsky = +70.0);
            Assert.AreEqual("12:00:00", p.toStringRA(ref b));
            Assert.AreEqual("-020:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState = MechanicalPoint.PointingStates.POINTING_NORMAL);
            Assert.AreEqual(0.0, p.RAsky    = +0.0);
            Assert.AreEqual(+70.0, p.DECsky = +70.0);
            Assert.AreEqual("00:00:00", p.toStringRA(ref b));
            Assert.AreEqual("+020:00:00", p.toStringDEC(ref b));
        }
        public void Test_DEC_Conversions()
        {
            MechanicalPoint p = new MechanicalPoint();
            String          b = "";

            Assert.IsFalse(p.parseStringDEC("-I5:00:00"));
            Assert.AreEqual(-255.0, p.DECm);
            Assert.AreEqual("-I5:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("-255:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("-F5:00:00"));
            Assert.AreEqual(-225.0, p.DECm);
            Assert.AreEqual("-F5:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("-225:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("-B0:00:00"));
            Assert.AreEqual(-180.0, p.DECm);
            Assert.AreEqual("-B0:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("-180:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("-=5:00:00"));
            Assert.AreEqual(-135.0, p.DECm);
            Assert.AreEqual("-=5:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("-135:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("-90:00:00"));
            Assert.AreEqual(-90.0, p.DECm);
            Assert.AreEqual("-90:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("-090:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("-45:00:00"));
            Assert.AreEqual(-45.0, p.DECm);
            Assert.AreEqual("-45:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("-045:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("+00:00:00"));
            Assert.AreEqual(+0.0, p.DECm);
            Assert.AreEqual("+00:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("+000:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("+45:00:00"));
            Assert.AreEqual(+45.0, p.DECm);
            Assert.AreEqual("+45:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("+045:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("+90:00:00"));
            Assert.AreEqual(+90.0, p.DECm);
            Assert.AreEqual("+90:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("+090:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("+=5:00:00"));
            Assert.AreEqual(+135.0, p.DECm);
            Assert.AreEqual("+=5:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("+135:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("+B0:00:00"));
            Assert.AreEqual(+180.0, p.DECm);
            Assert.AreEqual("+B0:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("+180:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("+F5:00:00"));
            Assert.AreEqual(+225.0, p.DECm);
            Assert.AreEqual("+F5:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("+225:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("+I5:00:00"));
            Assert.AreEqual(+255.0, p.DECm);
            Assert.AreEqual("+I5:00:00", p.toStringDEC_Sim(ref b));
            Assert.AreEqual("+255:00:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("+00:00:01"));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);
            Assert.IsTrue(Math.Abs(p.DECm - (+1 / 3600.0)) <= (1 / 3600.0));
            Assert.AreEqual("+000:00:01", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);
            Assert.IsFalse(p.parseStringDEC("+00:01:00"));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);
            Assert.IsTrue(Math.Abs(p.DECm - (+1 / 60.0)) <= (1 / 3600.0));
            Assert.AreEqual("+000:01:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_NORMAL, p.PointingState);

            Assert.IsFalse(p.parseStringDEC("-00:00:01"));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState);
            Assert.IsTrue(Math.Abs(p.DECm - (-1 / 3600.0)) <= (1 / 3600.0));
            Assert.AreEqual("-000:00:01", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState);
            Assert.IsFalse(p.parseStringDEC("-00:01:00"));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState);
            Assert.IsTrue(Math.Abs(p.DECm - (-1 / 60.0)) <= (1 / 3600.0));
            Assert.AreEqual("-000:01:00", p.toStringDEC(ref b));
            Assert.AreEqual(MechanicalPoint.PointingStates.POINTING_BEYOND_POLE, p.PointingState);

            // Negative tests
            Assert.IsTrue(p.parseStringDEC("+J0:00:00"));
            Assert.IsTrue(p.parseStringDEC("-J0:00:00"));
        }