Beispiel #1
0
        public void VectorVelocity_Calculates_Velocity_And_Bearing_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var velocity = new VectorVelocity()
            {
                IsWesterlyVelocity  = worksheet.Bool("IsWesterlyVelocity"),
                IsSoutherlyVelocity = worksheet.Bool("IsSoutherlyVelocity"),
                EastWestVelocity    = worksheet.NShort("EastWestVelocity"),
                EastWestExceeded    = worksheet.Bool("EastWestExceeded"),
                NorthSouthVelocity  = worksheet.NShort("NorthSouthVelocity"),
                NorthSouthExceeded  = worksheet.Bool("NorthSouthExceeded"),
            };

            if (worksheet.String("Speed") == null)
            {
                Assert.IsNull(velocity.Speed);
            }
            else
            {
                Assert.AreEqual(worksheet.Double("Speed"), velocity.Speed.Value, 0.000001);
            }

            if (worksheet.String("Bearing") == null)
            {
                Assert.IsNull(velocity.Bearing);
            }
            else
            {
                Assert.AreEqual(worksheet.Double("Bearing"), velocity.Bearing.Value, 0.000001);
            }
        }
Beispiel #2
0
        public void PolarPlotter_Initialise_Initialises_The_Plotter_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var roundDegrees     = 0;
            var seenArgException = false;

            try {
                roundDegrees = worksheet.Int("RoundDegree");
                _Plotter.Initialise(
                    worksheet.Double("Latitude"),
                    worksheet.Double("Longitude"),
                    worksheet.Int("LowSlice"),
                    worksheet.Int("HighSlice"),
                    worksheet.Int("SliceHeight"),
                    roundDegrees
                    );
            } catch (ArgumentException) {
                seenArgException = true;
            }

            Assert.AreEqual(worksheet.Bool("ArgException"), seenArgException);
            if (!seenArgException)
            {
                var slices = _Plotter.TakeSnapshot();
                Assert.AreEqual(worksheet.Double("Latitude"), _Plotter.Latitude);
                Assert.AreEqual(worksheet.Double("Longitude"), _Plotter.Longitude);
                Assert.AreEqual(worksheet.Int("RoundDegree"), _Plotter.RoundToDegrees);
                Assert.AreEqual(worksheet.Int("CountSlices"), slices.Count);

                var expectedPlotsPerSlice = 360 / roundDegrees;
                foreach (var slice in slices)
                {
                    Assert.AreEqual(expectedPlotsPerSlice, slice.PolarPlots.Count);
                }

                for (var i = 1; i <= 5; ++i)
                {
                    var lowName  = String.Format("Low{0}", i);
                    var highName = String.Format("High{0}", i);
                    var lowText  = worksheet.String(lowName);
                    var highText = worksheet.String(highName);
                    if (lowText != null && highText != null)
                    {
                        var expectedLow  = lowText == "Min" ? int.MinValue : int.Parse(lowText);
                        var expectedHigh = highText == "Max" ? int.MaxValue : int.Parse(highText);
                        Assert.IsTrue(slices.Any(r => r.AltitudeLower == expectedLow && r.AltitudeHigher == expectedHigh), "Could not find {0}-{1}", lowText, highText);
                    }
                }
            }
        }
        public void JsonSerialiser_WriteObject_Writes_ValueTypes_Correctly_For_Non_UK_Cultures()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            foreach (var culture in new string[] { "en-US", "de-DE", "fr-FR", "ru-RU" })
            {
                using (var cultureSwitcher = new CultureSwitcher(culture)) {
                    TestCleanup();
                    TestInitialise();

                    var obj = new ValueTypes()
                    {
                        BoolValue        = worksheet.Bool("BoolValue"),
                        UnusedBool       = worksheet.Bool("UnusedBool"),
                        NullableBool     = worksheet.NBool("NullableBool"),
                        Int              = worksheet.Int("Int"),
                        NullableInt      = worksheet.NInt("NullableInt"),
                        Long             = worksheet.Long("Long"),
                        NullableLong     = worksheet.NLong("NullableLong"),
                        Float            = worksheet.Float("Float"),
                        NullableFloat    = worksheet.NFloat("NullableFloat"),
                        Double           = worksheet.Double("Double"),
                        NullableDouble   = worksheet.NDouble("NullableDouble"),
                        DateTime         = worksheet.DateTime("DateTime"),
                        NullableDateTime = worksheet.NDateTime("NullableDateTime"),
                    };

                    _JsonSerialiser.Initialise(typeof(ValueTypes));
                    _JsonSerialiser.WriteObject(_Stream, obj);

                    var message = String.Format("when culture is {0}", culture);
                    Assert.AreEqual(worksheet.EString("Json"), GetJson(), message);
                }
            }
        }
        public void JsonSerialiser_WriteObject_Writes_ValueTypes_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var obj = new ValueTypes()
            {
                BoolValue        = worksheet.Bool("BoolValue"),
                UnusedBool       = worksheet.Bool("UnusedBool"),
                NullableBool     = worksheet.NBool("NullableBool"),
                Int              = worksheet.Int("Int"),
                NullableInt      = worksheet.NInt("NullableInt"),
                Long             = worksheet.Long("Long"),
                NullableLong     = worksheet.NLong("NullableLong"),
                Float            = worksheet.Float("Float"),
                NullableFloat    = worksheet.NFloat("NullableFloat"),
                Double           = worksheet.Double("Double"),
                NullableDouble   = worksheet.NDouble("NullableDouble"),
                DateTime         = worksheet.DateTime("DateTime"),
                NullableDateTime = worksheet.NDateTime("NullableDateTime"),
            };

            _JsonSerialiser.Initialise(typeof(ValueTypes));
            _JsonSerialiser.WriteObject(_Stream, obj);

            Assert.AreEqual(worksheet.EString("Json"), GetJson());
        }
        public void VectorVelocity_Calculates_Velocity_And_Bearing_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var velocity = new VectorVelocity() {
                IsWesterlyVelocity = worksheet.Bool("IsWesterlyVelocity"),
                IsSoutherlyVelocity = worksheet.Bool("IsSoutherlyVelocity"),
                EastWestVelocity = worksheet.NShort("EastWestVelocity"),
                EastWestExceeded = worksheet.Bool("EastWestExceeded"),
                NorthSouthVelocity = worksheet.NShort("NorthSouthVelocity"),
                NorthSouthExceeded = worksheet.Bool("NorthSouthExceeded"),
            };

            if(worksheet.String("Speed") == null) Assert.IsNull(velocity.Speed);
            else Assert.AreEqual(worksheet.Double("Speed"), velocity.Speed.Value, 0.000001);

            if(worksheet.String("Bearing") == null) Assert.IsNull(velocity.Bearing);
            else Assert.AreEqual(worksheet.Double("Bearing"), velocity.Bearing.Value, 0.000001);
        }
Beispiel #6
0
        public void CompactPositionReporting_Encode_Produces_Correct_Results_For_CPR101_Tables()
        {
            // The values for this test are all taken directly from the transition latitude test tables in 1090-WP30-12 Proposed New Appendix CPR101.
            var worksheet = new ExcelWorksheetData(TestContext);

            var numberOfBits     = worksheet.Byte("Bits");
            var oddFormat        = worksheet.Bool("OddFormat");
            var latitude         = worksheet.Double("Latitude");
            var longitude        = worksheet.Double("Longitude");
            var globalCoordinate = new GlobalCoordinate(latitude, longitude);

            var expectedLatitude  = Convert.ToInt32(worksheet.String("ExpectedLatitude"), 16);
            var expectedLongitude = Convert.ToInt32(worksheet.String("ExpectedLongitude"), 16);
            var dataRow           = worksheet.Int("DataRow"); // helps set conditional breakpoints, VSTS doesn't always process rows in ascending order as they appear in the worksheet

            // In testing some of the input latitudes and longitudes couldn't produce the expected results from table 6-1 etc. of 1090-WP30-12 because of small
            // rounding errors in the handling of doubles. Switching to decimals didn't help and it would make the code slower because the FPU doesn't work with
            // decimals. So the "RELatitude" and "RELongitude" columns were added - if they are empty then the code is expected to produce the values in
            // the Expected columns, which corresponds with the test results from 1090-WP30-12, but if they contain values then these are the actual results after
            // the rounding error has had its wicked way. In most cases they are 1 out for latitude but that can move the resolved latitude into a different NL and produce
            // a large difference in longitude. There are very few of these anomalies, they represent errors of a few feet and as this isn't going into an aircraft I can't
            // say I'm too bothered about them. However I do want them to be obvious in the test data, hence the reason for adding new columns rather than just changing
            // the expected results.
            int?reLatitude  = null;
            int?reLongitude = null;

            if (worksheet.String("RELatitude") != null)
            {
                reLatitude  = Convert.ToInt32(worksheet.String("RELatitude"), 16);
                reLongitude = Convert.ToInt32(worksheet.String("RELongitude"), 16);
            }

            var coordinate = _Cpr.Encode(globalCoordinate, oddFormat, numberOfBits);

            Assert.AreEqual(reLatitude ?? expectedLatitude, coordinate.Latitude);
            Assert.AreEqual(reLongitude ?? expectedLongitude, coordinate.Longitude);
            Assert.AreEqual(numberOfBits, coordinate.NumberOfBits);
            Assert.AreEqual(oddFormat, coordinate.OddFormat);
        }
Beispiel #7
0
        public void CompactPositionReporting_LocalDecode_Produces_Correct_Results_For_CPR101_Tables()
        {
            // The values for this test are all taken directly from the transition latitude test tables in 1090-WP30-12 Proposed New Appendix CPR101
            var worksheet = new ExcelWorksheetData(TestContext);

            var numberOfBits      = worksheet.Byte("Bits");
            var oddFormat         = worksheet.Bool("OddFormat");
            var encodedLatitude   = Convert.ToInt32(worksheet.String("ExpectedLatitude"), 16);
            var encodedLongitude  = Convert.ToInt32(worksheet.String("ExpectedLongitude"), 16);
            var expectedLatitude  = worksheet.Double("Latitude");
            var expectedLongitude = worksheet.Double("Longitude");
            var cprCoordinate     = new CompactPositionReportingCoordinate(encodedLatitude, encodedLongitude, oddFormat, numberOfBits);

            // The reference latitude and longitude is set to roughly 50km of the expected latitude and longitude
            double?referenceLatitude, referenceLongitude;

            GreatCircleMaths.Destination(expectedLatitude, expectedLongitude, 45, 50, out referenceLatitude, out referenceLongitude);
            var referenceCoordinate = new GlobalCoordinate(referenceLatitude.Value, referenceLongitude.Value);

            var dataRow = worksheet.Int("DataRow"); // helps set conditional breakpoints, VSTS doesn't always process rows in ascending order as they appear in the worksheet

            var decodedCoordinate = _Cpr.LocalDecode(cprCoordinate, referenceCoordinate);

            // We need to accept 180 and -180 as being the same longitude, taking into account rounding errors
            if (expectedLongitude == -180.0 && decodedCoordinate.Longitude > 179.9999999999)
            {
                expectedLongitude = 180.0;
            }
            else if (expectedLongitude == 180.0 && decodedCoordinate.Longitude < -179.9999999999)
            {
                expectedLongitude = -180.0;
            }

            Assert.AreEqual(expectedLatitude, decodedCoordinate.Latitude, 0.0008);           // The CPR tables cover all latitudes, sometimes the rounding introduced by selecting the midpoint of a zone can be quite large
            Assert.AreEqual(expectedLongitude, decodedCoordinate.Longitude, 0.000000000001); // This can have a lower tolerance as the CPR101 tables aren't testing longitude zone boundaries so much
        }
        public void CompactPositionReporting_Encode_Produces_Correct_Results_For_CPR101_Tables()
        {
            // The values for this test are all taken directly from the transition latitude test tables in 1090-WP30-12 Proposed New Appendix CPR101.
            var worksheet = new ExcelWorksheetData(TestContext);

            var numberOfBits = worksheet.Byte("Bits");
            var oddFormat = worksheet.Bool("OddFormat");
            var latitude = worksheet.Double("Latitude");
            var longitude = worksheet.Double("Longitude");
            var globalCoordinate = new GlobalCoordinate(latitude, longitude);

            var expectedLatitude = Convert.ToInt32(worksheet.String("ExpectedLatitude"), 16);
            var expectedLongitude = Convert.ToInt32(worksheet.String("ExpectedLongitude"), 16);
            var dataRow = worksheet.Int("DataRow"); // helps set conditional breakpoints, VSTS doesn't always process rows in ascending order as they appear in the worksheet

            // In testing some of the input latitudes and longitudes couldn't produce the expected results from table 6-1 etc. of 1090-WP30-12 because of small
            // rounding errors in the handling of doubles. Switching to decimals didn't help and it would make the code slower because the FPU doesn't work with
            // decimals. So the "RELatitude" and "RELongitude" columns were added - if they are empty then the code is expected to produce the values in
            // the Expected columns, which corresponds with the test results from 1090-WP30-12, but if they contain values then these are the actual results after
            // the rounding error has had its wicked way. In most cases they are 1 out for latitude but that can move the resolved latitude into a different NL and produce
            // a large difference in longitude. There are very few of these anomalies, they represent errors of a few feet and as this isn't going into an aircraft I can't
            // say I'm too bothered about them. However I do want them to be obvious in the test data, hence the reason for adding new columns rather than just changing
            // the expected results.
            int? reLatitude = null;
            int? reLongitude = null;
            if(worksheet.String("RELatitude") != null) {
                reLatitude = Convert.ToInt32(worksheet.String("RELatitude"), 16);
                reLongitude = Convert.ToInt32(worksheet.String("RELongitude"), 16);
            }

            var coordinate = _Cpr.Encode(globalCoordinate, oddFormat, numberOfBits);
            Assert.AreEqual(reLatitude ?? expectedLatitude, coordinate.Latitude);
            Assert.AreEqual(reLongitude ?? expectedLongitude, coordinate.Longitude);
            Assert.AreEqual(numberOfBits, coordinate.NumberOfBits);
            Assert.AreEqual(oddFormat, coordinate.OddFormat);
        }
Beispiel #9
0
        public void PolarPlotter_AddCoordinate_Adds_Plot_To_All_Applicable_Slices()
        {
            var worksheet = new ExcelWorksheetData(TestContext);
            var comment   = worksheet.String("Comments");

            //if(comment != "comment here") return;

            StandardInitialise();

            for (var i = 1; i <= 2; ++i)
            {
                var altitude  = worksheet.NInt(String.Format("Altitude{0}", i));
                var latitude  = worksheet.NDouble(String.Format("Latitude{0}", i));
                var longitude = worksheet.NDouble(String.Format("Longitude{0}", i));
                if (altitude != null && latitude != null && longitude != null)
                {
                    _Plotter.AddCoordinate(1, altitude.Value, latitude.Value, longitude.Value);
                }
            }

            foreach (var slice in _Plotter.TakeSnapshot())
            {
                string suffix;
                switch (slice.AltitudeHigher)
                {
                case 9:     suffix = "-09"; break;

                case 19:    suffix = slice.AltitudeLower == 10 ? "-19" : "-RG"; break;

                default:    suffix = "-ALL"; break;
                }
                var nonZeroPolarPlots = slice.PolarPlots.Where(r => r.Value.Distance != 0).ToDictionary(r => r.Key, r => r.Value);
                Assert.AreEqual(worksheet.Int(String.Format("Count{0}", suffix)), nonZeroPolarPlots.Count, suffix);
                for (var i = 1; i <= nonZeroPolarPlots.Count; ++i)
                {
                    var bearing = worksheet.Int(String.Format("Ang{0}{1}", i, suffix));
                    var plot    = nonZeroPolarPlots[bearing];
                    Assert.AreEqual(worksheet.Int(String.Format("Alt{0}{1}", i, suffix)), plot.Altitude, suffix);
                    Assert.AreEqual(worksheet.Double(String.Format("Dist{0}{1}", i, suffix)), plot.Distance, 0.0001, suffix);
                    Assert.AreEqual(bearing, plot.Angle, suffix);
                }
            }
        }
Beispiel #10
0
        public void AircraftSanityChecker_CheckAltitude_Returns_Correct_Values()
        {
            var worksheet = new ExcelWorksheetData(TestContext);
            //if(!worksheet.NBool("JustThis").GetValueOrDefault()) continue;

            var comments = worksheet.String("Comments");

            for (var i = 1; i <= 5; ++i)
            {
                var altitude = worksheet.NInt(String.Format("Altitude{0}", i));
                if (altitude != null)
                {
                    var seconds        = worksheet.Double(String.Format("Seconds{0}", i));
                    var time           = new DateTime(2014, 8, 3).AddSeconds(seconds);
                    var expectedResult = worksheet.ParseEnum <Certainty>(String.Format("Result{0}", i));
                    var actualResult   = _Checker.CheckAltitude(1, time, altitude.Value);
                    Assert.AreEqual(expectedResult, actualResult, String.Format("Column {0} {1}", i, comments));
                }
            }
        }
Beispiel #11
0
        public void AircraftSanityChecker_FirstGoodPosition_Returns_Correct_Values()
        {
            var worksheet = new ExcelWorksheetData(TestContext);
            //if(!worksheet.NBool("JustThis").GetValueOrDefault()) continue;

            var comments = worksheet.String("Comments");

            for (var i = 1; i <= 5; ++i)
            {
                var distance = worksheet.NDouble(String.Format("Distance{0}", i));
                if (distance != null)
                {
                    var seconds        = worksheet.Double(String.Format("Seconds{0}", i));
                    var time           = new DateTime(2014, 8, 3).AddSeconds(seconds);
                    var expectedResult = worksheet.NDouble(String.Format("1stGood{0}", i));

                    double?latitude, longitude;
                    GreatCircleMaths.Destination(51.0, -0.6, 90.0, distance, out latitude, out longitude);

                    _Checker.CheckPosition(1, time, latitude.Value, longitude.Value);
                    var globalCoordinates = _Checker.FirstGoodPosition(1);

                    double?actualResult = null;
                    if (globalCoordinates != null)
                    {
                        actualResult = GreatCircleMaths.Distance(51.0, -0.6, globalCoordinates.Latitude, globalCoordinates.Longitude);
                    }

                    var message = String.Format("Column {0} {1}", i, comments);
                    if (expectedResult == null)
                    {
                        Assert.IsNull(actualResult, message);
                    }
                    else
                    {
                        Assert.AreEqual(expectedResult.Value, actualResult ?? double.MinValue, 0.001, message);
                    }
                }
            }
        }
Beispiel #12
0
        public void AircraftSanityChecker_CheckPosition_Returns_Correct_Values()
        {
            var worksheet = new ExcelWorksheetData(TestContext);
            //if(!worksheet.NBool("JustThis").GetValueOrDefault()) continue;

            var comments = worksheet.String("Comments");

            for (var i = 1; i <= 5; ++i)
            {
                var distance = worksheet.NDouble(String.Format("Distance{0}", i));
                if (distance != null)
                {
                    var seconds        = worksheet.Double(String.Format("Seconds{0}", i));
                    var time           = new DateTime(2014, 8, 3).AddSeconds(seconds);
                    var expectedResult = worksheet.ParseEnum <Certainty>(String.Format("Result{0}", i));

                    double?latitude, longitude;
                    GreatCircleMaths.Destination(51.0, -0.6, 90.0, distance, out latitude, out longitude);

                    var actualResult = _Checker.CheckPosition(1, time, latitude.Value, longitude.Value);
                    Assert.AreEqual(expectedResult, actualResult, String.Format("Column {0} {1}", i, comments));
                }
            }
        }
        private void DoValidationTest(Action triggerValidation, bool doSuppressExcessiveFileSystemCheck = false)
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            List<ValidationResult> validationResults = new List<ValidationResult>();
            _View.Setup(v => v.ShowValidationResults(It.IsAny<IEnumerable<ValidationResult>>())).Callback((IEnumerable<ValidationResult> results) => {
                foreach(var validationResult in results) validationResults.Add(validationResult);
            });

            int countFileExistsCalls = 0;
            _Provider.Setup(p => p.FileExists(It.IsAny<string>())).Returns(false);
            _Provider.Setup(p => p.FileExists(null)).Callback(() => {throw new NullReferenceException(); });
            _Provider.Setup(p => p.FileExists("FileExists")).Callback(() => countFileExistsCalls++).Returns(true);

            int countFolderExistsCalls = 0;
            _Provider.Setup(p => p.FolderExists(It.IsAny<string>())).Returns(false);
            _Provider.Setup(p => p.FolderExists(null)).Callback(() => {throw new NullReferenceException(); });
            _Provider.Setup(p => p.FolderExists("FolderExists")).Callback(() => countFolderExistsCalls++).Returns(true);

            _Presenter.Initialise(_View.Object);

            _View.Object.BaseStationDatabaseFileName = null;
            _View.Object.OperatorFlagsFolder = null;
            _View.Object.SilhouettesFolder = null;

            for(var i = 1;i <= 3;++i) {
                var uiFieldColumn = String.Format("UIField{0}", i);
                var valueColumn = String.Format("Value{0}", i);
                if(worksheet.String(uiFieldColumn) != null) {
                    switch(worksheet.String(uiFieldColumn)) {
                        case "AcceptableAirborneSpeed":             _View.Object.RawDecodingAcceptableAirborneSpeed = worksheet.Double(valueColumn); break;
                        case "AcceptableAirSurfaceTransitionSpeed": _View.Object.RawDecodingAcceptableAirSurfaceTransitionSpeed = worksheet.Double(valueColumn); break;
                        case "AcceptableSurfaceSpeed":              _View.Object.RawDecodingAcceptableSurfaceSpeed = worksheet.Double(valueColumn); break;
                        case "AcceptIcaoInNonPICount":              _View.Object.AcceptIcaoInNonPICount = worksheet.Int(valueColumn); break;
                        case "AcceptIcaoInNonPISeconds":            _View.Object.AcceptIcaoInNonPISeconds = worksheet.Int(valueColumn); break;
                        case "AcceptIcaoInPI0Count":                _View.Object.AcceptIcaoInPI0Count = worksheet.Int(valueColumn); break;
                        case "AcceptIcaoInPI0Seconds":              _View.Object.AcceptIcaoInPI0Seconds = worksheet.Int(valueColumn); break;
                        case "AirborneGlobalPositionLimit":         _View.Object.RawDecodingAirborneGlobalPositionLimit = worksheet.Int(valueColumn); break;
                        case "BaseStationAddress":                  _View.Object.BaseStationAddress = worksheet.EString(valueColumn); break;
                        case "BaseStationConnectionType":           _View.Object.BaseStationConnectionType = worksheet.ParseEnum<ConnectionType>(valueColumn); break;
                        case "BaseStationPort":                     _View.Object.BaseStationPort = worksheet.Int(valueColumn); break;
                        case "CheckForNewVersionsPeriodDays":       _View.Object.CheckForNewVersionsPeriodDays = worksheet.Int(valueColumn); break;
                        case "DatabaseFileName":                    _View.Object.BaseStationDatabaseFileName = worksheet.EString(valueColumn); break;
                        case "DisplayTimeoutSeconds":               _View.Object.DisplayTimeoutSeconds = worksheet.Int(valueColumn); break;
                        case "FastSurfaceGlobalPositionLimit":      _View.Object.RawDecodingFastSurfaceGlobalPositionLimit = worksheet.Int(valueColumn); break;
                        case "FlagsFolder":                         _View.Object.OperatorFlagsFolder = worksheet.EString(valueColumn); break;
                        case "InitialGoogleMapLatitude":            _View.Object.InitialGoogleMapLatitude = worksheet.Double(valueColumn); break;
                        case "InitialGoogleMapLongitude":           _View.Object.InitialGoogleMapLongitude = worksheet.Double(valueColumn); break;
                        case "InitialGoogleMapZoom":                _View.Object.InitialGoogleMapZoom = worksheet.Int(valueColumn); break;
                        case "InitialRefreshSeconds":               _View.Object.InitialGoogleMapRefreshSeconds = worksheet.Int(valueColumn); break;
                        case "InternetClientTimeoutMinutes":        _View.Object.InternetClientTimeoutMinutes = worksheet.Int(valueColumn); break;
                        case "MinimumRefreshSeconds":               _View.Object.MinimumGoogleMapRefreshSeconds = worksheet.Int(valueColumn); break;
                        case "PicturesFolder":                      _View.Object.PicturesFolder = worksheet.EString(valueColumn); break;
                        case "ReceiverRange":                       _View.Object.RawDecodingReceiverRange = worksheet.Int(valueColumn); break;
                        case "SerialBaudRate":                      _View.Object.SerialBaudRate = worksheet.Int(valueColumn); break;
                        case "SerialComPort":                       _View.Object.SerialComPort = worksheet.EString(valueColumn); break;
                        case "SerialDataBits":                      _View.Object.SerialDataBits = worksheet.Int(valueColumn); break;
                        case "ShortTrailLengthSeconds":             _View.Object.ShortTrailLengthSeconds = worksheet.Int(valueColumn); break;
                        case "SilhouettesFolder":                   _View.Object.SilhouettesFolder = worksheet.EString(valueColumn); break;
                        case "SlowSurfaceGlobalPositionLimit":      _View.Object.RawDecodingSlowSurfaceGlobalPositionLimit = worksheet.Int(valueColumn); break;
                        case "TextToSpeechSpeed":                   _View.Object.TextToSpeechSpeed = worksheet.Int(valueColumn); break;
                        case "TrackingTimeoutSeconds":              _View.Object.TrackingTimeoutSeconds = worksheet.Int(valueColumn); break;
                        case "UPnpPort":                            _View.Object.UPnpPort = worksheet.Int(valueColumn); break;
                        case "WebAuthenticateUser":                 _View.Object.WebServerUserMustAuthenticate = worksheet.Bool(valueColumn); break;
                        case "WebUserName":                         _View.Object.WebServerUserName = worksheet.EString(valueColumn); break;
                        default:                                    throw new NotImplementedException();
                    }
                }
            }

            triggerValidation();
            _View.Verify(v => v.ShowValidationResults(It.IsAny<IEnumerable<ValidationResult>>()), Times.Once());

            if(doSuppressExcessiveFileSystemCheck) {
                validationResults.Clear();

                triggerValidation();
                _View.Verify(v => v.ShowValidationResults(It.IsAny<IEnumerable<ValidationResult>>()), Times.Exactly(2));

                Assert.IsTrue(countFileExistsCalls < 2);
                Assert.IsTrue(countFolderExistsCalls < 2);
            }

            var validationErrorSummary = new StringBuilder();
            foreach(var validationResult in validationResults) {
                if(validationErrorSummary.Length != 0) validationErrorSummary.Append("; ");
                validationErrorSummary.AppendFormat("{0}:{1}", validationResult.Field, validationResult.Message);
            }

            Assert.AreEqual(worksheet.Int("CountErrors"), validationResults.Count(), validationErrorSummary.ToString());
            if(validationResults.Count() > 0) {
                Assert.IsTrue(validationResults.Where(r => r.Field == worksheet.ParseEnum<ValidationField>("Field") &&
                                                           r.Message == worksheet.EString("Message") &&
                                                           r.IsWarning == worksheet.Bool("IsWarning")).Any(),
                              validationErrorSummary.ToString());
            }
        }
Beispiel #14
0
        public void ServerConfigJson_ToModel_Fills_Model_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var isLocalAddress = true;

            using (var cultureSwitcher = new CultureSwitcher(worksheet.String("Culture"))) {
                var configProperty = worksheet.String("ConfigProperty");
                var isMono         = worksheet.Bool("IsMono");
                _RuntimeEnvironment.Setup(r => r.IsMono).Returns(isMono);

                switch (configProperty)
                {
                case "VrsVersion":                  _ApplicationInformation.Setup(r => r.ShortVersion).Returns(worksheet.String("Value")); break;

                case "IsLocalAddress":              isLocalAddress = worksheet.Bool("Value"); break;

                case "IsMono":                      break;

                case "InitialMapLatitude":          _Configuration.GoogleMapSettings.InitialMapLatitude = worksheet.Double("Value"); break;

                case "InitialMapLongitude":         _Configuration.GoogleMapSettings.InitialMapLongitude = worksheet.Double("Value"); break;

                case "InitialMapType":              _Configuration.GoogleMapSettings.InitialMapType = worksheet.EString("Value"); break;

                case "InitialMapZoom":              _Configuration.GoogleMapSettings.InitialMapZoom = worksheet.Int("Value"); break;

                case "InitialRefreshSeconds":       _Configuration.GoogleMapSettings.InitialRefreshSeconds = worksheet.Int("Value"); break;

                case "InitialSettings":             _Configuration.GoogleMapSettings.InitialSettings = worksheet.EString("Value"); break;

                case "MinimumRefreshSeconds":       _Configuration.GoogleMapSettings.MinimumRefreshSeconds = worksheet.Int("Value"); break;

                case "InitialDistanceUnit":         _Configuration.GoogleMapSettings.InitialDistanceUnit = worksheet.ParseEnum <DistanceUnit>("Value"); break;

                case "InitialHeightUnit":           _Configuration.GoogleMapSettings.InitialHeightUnit = worksheet.ParseEnum <HeightUnit>("Value"); break;

                case "InitialSpeedUnit":            _Configuration.GoogleMapSettings.InitialSpeedUnit = worksheet.ParseEnum <SpeedUnit>("Value"); break;

                case "CanRunReports":               _Configuration.InternetClientSettings.CanRunReports = worksheet.Bool("Value"); break;

                case "CanShowPinText":              _Configuration.InternetClientSettings.CanShowPinText = worksheet.Bool("Value"); break;

                case "TimeoutMinutes":              _Configuration.InternetClientSettings.TimeoutMinutes = worksheet.Int("Value"); break;

                case "CanPlayAudio":                _Configuration.InternetClientSettings.CanPlayAudio = worksheet.Bool("Value"); break;

                case "CanSubmitRoutes":             _Configuration.InternetClientSettings.CanSubmitRoutes = worksheet.Bool("Value"); break;

                case "CanShowPictures":             _Configuration.InternetClientSettings.CanShowPictures = worksheet.Bool("Value"); break;

                case "AudioEnabled":                _Configuration.AudioSettings.Enabled = worksheet.Bool("Value"); break;

                case "CanShowPolarPlots":           _Configuration.InternetClientSettings.CanShowPolarPlots = worksheet.Bool("Value"); break;

                case "UseMarkerLabels":             _Configuration.MonoSettings.UseMarkerLabels = worksheet.Bool("Value"); break;

                case "UseSvgGraphicsOnDesktop":     _Configuration.GoogleMapSettings.UseSvgGraphicsOnDesktop = worksheet.Bool("Value"); break;

                case "UseSvgGraphicsOnMobile":      _Configuration.GoogleMapSettings.UseSvgGraphicsOnMobile = worksheet.Bool("Value"); break;

                case "UseSvgGraphicsOnReports":     _Configuration.GoogleMapSettings.UseSvgGraphicsOnReports = worksheet.Bool("Value"); break;

                case "OpenStreetMapTileServerUrl":  _Configuration.GoogleMapSettings.OpenStreetMapTileServerUrl = worksheet.EString("Value"); break;

                default:                            throw new NotImplementedException();
                }
            }

            var model = ServerConfigJson.ToModel(isLocalAddress);

            var propertyName = worksheet.String("ConfigProperty");

            switch (propertyName)
            {
            case "VrsVersion":                      Assert.AreEqual(worksheet.EString("JsonValue"), model.VrsVersion); break;

            case "IsLocalAddress":                  Assert.AreEqual(worksheet.Bool("JsonValue"), model.IsLocalAddress); break;

            case "IsMono":                          Assert.AreEqual(worksheet.Bool("JsonValue"), model.IsMono); break;

            case "InitialMapLatitude":              Assert.AreEqual(worksheet.Double("JsonValue"), model.InitialLatitude); break;

            case "InitialMapLongitude":             Assert.AreEqual(worksheet.Double("JsonValue"), model.InitialLongitude); break;

            case "InitialMapType":                  Assert.AreEqual(worksheet.EString("JsonValue"), model.InitialMapType); break;

            case "InitialMapZoom":                  Assert.AreEqual(worksheet.Int("JsonValue"), model.InitialZoom); break;

            case "InitialRefreshSeconds":           Assert.AreEqual(worksheet.Int("JsonValue"), model.RefreshSeconds); break;

            case "InitialSettings":                 Assert.AreEqual(worksheet.EString("JsonValue"), model.InitialSettings); break;

            case "MinimumRefreshSeconds":           Assert.AreEqual(worksheet.Int("JsonValue"), model.MinimumRefreshSeconds); break;

            case "InitialDistanceUnit":             Assert.AreEqual(worksheet.String("JsonValue"), model.InitialDistanceUnit); break;

            case "InitialHeightUnit":               Assert.AreEqual(worksheet.String("JsonValue"), model.InitialHeightUnit); break;

            case "InitialSpeedUnit":                Assert.AreEqual(worksheet.String("JsonValue"), model.InitialSpeedUnit); break;

            case "CanRunReports":                   Assert.AreEqual(worksheet.Bool("JsonValue"), model.InternetClientCanRunReports); break;

            case "CanShowPinText":                  Assert.AreEqual(worksheet.Bool("JsonValue"), model.InternetClientCanShowPinText); break;

            case "TimeoutMinutes":                  Assert.AreEqual(worksheet.Int("JsonValue"), model.InternetClientTimeoutMinutes); break;

            case "CanPlayAudio":                    Assert.AreEqual(worksheet.Bool("JsonValue"), model.InternetClientsCanPlayAudio); break;

            case "CanSubmitRoutes":                 Assert.AreEqual(worksheet.Bool("JsonValue"), model.InternetClientsCanSubmitRoutes); break;

            case "CanShowPictures":                 Assert.AreEqual(worksheet.Bool("JsonValue"), model.InternetClientsCanSeeAircraftPictures); break;

            case "AudioEnabled":                    Assert.AreEqual(worksheet.Bool("JsonValue"), model.IsAudioEnabled); break;

            case "CanShowPolarPlots":               Assert.AreEqual(worksheet.Bool("JsonValue"), model.InternetClientsCanSeePolarPlots); break;

            case "UseMarkerLabels":                 Assert.AreEqual(worksheet.Bool("JsonValue"), model.UseMarkerLabels); break;

            case "UseSvgGraphicsOnDesktop":         Assert.AreEqual(worksheet.Bool("JsonValue"), model.UseSvgGraphicsOnDesktop); break;

            case "UseSvgGraphicsOnMobile":          Assert.AreEqual(worksheet.Bool("JsonValue"), model.UseSvgGraphicsOnMobile); break;

            case "UseSvgGraphicsOnReports":         Assert.AreEqual(worksheet.Bool("JsonValue"), model.UseSvgGraphicsOnReports); break;

            case "OpenStreetMapTileServerUrl":      Assert.AreEqual(worksheet.EString("JsonValue"), model.OpenStreetMapTileServerUrl); break;

            default:                                throw new NotImplementedException();
            }
        }
        public void RawMessageTranslator_Translate_Extracts_Position_From_ADSB_Messages_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Translator.ReceiverLocation = ParseGlobalPosition(worksheet.String("ReceiverPosn"));
            _Translator.ReceiverRangeKilometres = worksheet.Int("Range");
            _Translator.GlobalDecodeAirborneThresholdMilliseconds = worksheet.Int("GATS");
            _Translator.GlobalDecodeFastSurfaceThresholdMilliseconds = worksheet.Int("GFSTS");
            _Translator.GlobalDecodeSlowSurfaceThresholdMilliseconds = worksheet.Int("GSSTS");
            _Translator.LocalDecodeMaxSpeedAirborne = worksheet.Double("LAMS");
            _Translator.LocalDecodeMaxSpeedTransition = worksheet.Double("LTMS");
            _Translator.LocalDecodeMaxSpeedSurface = worksheet.Double("LSMS");
            _Translator.SuppressReceiverRangeCheck = worksheet.Bool("SRRC");
            _Translator.UseLocalDecodeForInitialPosition = worksheet.Bool("ULD");

            DateTime now = DateTime.UtcNow;
            for(var i = 1;i <= 4;++i) {
                var millisecondsColumn = String.Format("MSec{0}", i);
                var cprColumn = String.Format("CPR{0}", i);
                var speedColumn = String.Format("Spd{0}", i);
                var positionColumn = String.Format("Posn{0}", i);

                if(worksheet.String(cprColumn) == null) continue;
                var cpr = ParseCpr(worksheet.String(cprColumn));
                var speed = worksheet.NDouble(speedColumn);
                var expectedPosition = ParseGlobalPosition(worksheet.String(positionColumn));

                if(i != 1 && worksheet.String(millisecondsColumn) != null) {
                    now = now.AddMilliseconds(worksheet.Int(millisecondsColumn));
                }

                var modeSMessage = new ModeSMessage() { DownlinkFormat = DownlinkFormat.ExtendedSquitter, Icao24 = 0x112233, ParityInterrogatorIdentifier = 0 };
                var adsbMessage = new AdsbMessage(modeSMessage);
                switch(cpr.NumberOfBits) {
                    case 17:
                        adsbMessage.MessageFormat = MessageFormat.AirbornePosition;
                        adsbMessage.AirbornePosition = new AirbornePositionMessage() { CompactPosition = cpr };
                        break;
                    case 19:
                        adsbMessage.MessageFormat = MessageFormat.SurfacePosition;
                        adsbMessage.SurfacePosition = new SurfacePositionMessage() { CompactPosition = cpr, GroundSpeed = speed, };
                        break;
                }

                var baseStationMessage = _Translator.Translate(now, modeSMessage, adsbMessage);

                var failMessage = String.Format("Failed on message {0}", i);
                if(expectedPosition == null) {
                    if(baseStationMessage != null) {
                        if(baseStationMessage.Latitude != null || baseStationMessage.Longitude != null) {
                            Assert.Fail(String.Format("Position decoded to {0}/{1} erroneously. {2}", baseStationMessage.Latitude, baseStationMessage.Longitude, failMessage));
                        }
                    }
                } else {
                    Assert.IsNotNull(baseStationMessage.Latitude, failMessage);
                    Assert.IsNotNull(baseStationMessage.Longitude, failMessage);
                    Assert.AreEqual(expectedPosition.Latitude, baseStationMessage.Latitude.Value, 0.0001, failMessage);
                    Assert.AreEqual(expectedPosition.Longitude, baseStationMessage.Longitude.Value, 0.0001, failMessage);
                }
            }

            Assert.AreEqual(worksheet.Int("ResetCount"), _PositionResetEvent.CallCount);
            Assert.AreEqual(worksheet.Int("ResetCount") > 0 ? 1L : 0L, _Statistics.AdsbPositionsReset);
            Assert.AreEqual(worksheet.Long("BadRange"), _Statistics.AdsbPositionsOutsideRange);
            Assert.AreEqual(worksheet.Long("BadSpeed"), _Statistics.AdsbPositionsExceededSpeedCheck);
        }
        public void FlightSimulatorXPresenter_RidingAircraft_Approximates_Bank_Angle_From_Track()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Presenter.Initialise(_View.Object);

            WriteAircraftInformation aircraftInformation = new WriteAircraftInformation();
            _FlightSimulatorX.Setup(f => f.MoveAircraft(It.IsAny<WriteAircraftInformation>())).Callback((WriteAircraftInformation writeAircraftInformation) => {
                aircraftInformation = writeAircraftInformation;
            });

            _FlightSimulatorX.Setup(f => f.Connected).Returns(true);
            _FlightSimulatorX.Raise(f => f.ConnectionStatusChanged += null, EventArgs.Empty);

            _SelectedAircraft.UniqueId = 1;

            _View.Raise(v => v.RideAircraftClicked += null, EventArgs.Empty);

            for(var i = 1;i <= 3;++i) {
                string uniqueIdColumn = String.Format("UniqueId{0}", i);
                string updateTimeColumn = String.Format("UpdateTime{0}", i);
                string trackColumn = String.Format("Track{0}", i);
                string bankColumn = String.Format("Bank{0}", i);

                if(worksheet.String(uniqueIdColumn) == null) break;

                var aircraft = new Mock<IAircraft>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties().Object;
                if(_RealAircraftList.Count == 0) _RealAircraftList.Add(aircraft);
                else                             _RealAircraftList[0] = aircraft;

                _SelectedAircraft.UniqueId = aircraft.UniqueId = worksheet.Int(uniqueIdColumn);
                aircraft.LastUpdate = worksheet.DateTime(updateTimeColumn);
                aircraft.Track = worksheet.NFloat(trackColumn);
                _View.Raise(v => v.RefreshFlightSimulatorXInformation += null, EventArgs.Empty);
                Assert.AreEqual(worksheet.Double(bankColumn), aircraftInformation.Bank, i.ToString());
            }
        }
        public void FlightSimulatorXPresenter_RidingAircraft_Sends_Real_World_Aircraft_Information_To_FSX_On_View_Timer_Tick()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Presenter.Initialise(_View.Object);

            _Provider.Setup(p => p.UtcNow).Returns(worksheet.DateTime("UtcNow"));

            _SelectedAircraft.UniqueId = 92;

            var aircraft = new Mock<IAircraft>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties();
            _RealAircraftList.Add(aircraft.Object);
            aircraft.Object.UniqueId = 92;
            aircraft.Object.Latitude = worksheet.NFloat("Latitude");
            aircraft.Object.Longitude = worksheet.NFloat("Longitude");
            aircraft.Object.PositionTime = worksheet.NDateTime("PositionTime");
            aircraft.Object.GroundSpeed = worksheet.NFloat("GroundSpeed");
            aircraft.Object.Track = worksheet.NFloat("Track");
            aircraft.Object.Type = worksheet.String("Type");
            aircraft.Object.Model = worksheet.String("Model");
            aircraft.Object.Operator = worksheet.String("Operator");
            aircraft.Object.Registration = worksheet.String("Registration");
            aircraft.Object.Squawk = worksheet.NInt("Squawk");
            aircraft.Object.Altitude = worksheet.NInt("Altitude");
            aircraft.Object.VerticalRate = worksheet.NInt("VerticalRate");

            WriteAircraftInformation aircraftInformation = new WriteAircraftInformation();
            _FlightSimulatorX.Setup(f => f.MoveAircraft(It.IsAny<WriteAircraftInformation>())).Callback((WriteAircraftInformation writeAircraftInformation) => {
                aircraftInformation = writeAircraftInformation;
            });

            _FlightSimulatorX.Setup(f => f.Connected).Returns(true);
            _FlightSimulatorX.Raise(f => f.ConnectionStatusChanged += null, EventArgs.Empty);

            _View.Raise(v => v.RideAircraftClicked += null, EventArgs.Empty);
            _View.Raise(v => v.RefreshFlightSimulatorXInformation += null, EventArgs.Empty);

            _FlightSimulatorX.Verify(f => f.MoveAircraft(It.IsAny<WriteAircraftInformation>()), Times.Once());

            Assert.AreEqual(worksheet.Double("FSXAirspeedIndicated"), aircraftInformation.AirspeedIndicated);
            Assert.AreEqual(worksheet.Double("FSXAltitude"), aircraftInformation.Altitude);
            Assert.AreEqual(worksheet.Double("FSXLatitude"), aircraftInformation.Latitude, 0.001);
            Assert.AreEqual(worksheet.Double("FSXLongitude"), aircraftInformation.Longitude, 0.001);
            Assert.AreEqual(worksheet.String("FSXOperator"), aircraftInformation.Operator);
            Assert.AreEqual(worksheet.String("FSXRegistration"), aircraftInformation.Registration);
            Assert.AreEqual(worksheet.Double("FSXTrueHeading"), aircraftInformation.TrueHeading, 0.001);
            Assert.AreEqual(worksheet.Double("FSXVerticalSpeed"), aircraftInformation.VerticalSpeed);
        }
        public void FlightSimulatorXPresenter_Requested_Aircraft_Information_Is_Copied_Into_FlightSimulatorAircraftList()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Presenter.Initialise(_View.Object);

            var utcNow = worksheet.DateTime("UtcNow");
            _Provider.Setup(p => p.UtcNow).Returns(utcNow);

            var aircraftInformation = new ReadAircraftInformation() {
                AirspeedIndicated = worksheet.Double("FSXAirspeedIndicated"),
                Altitude = worksheet.Double("FSXAltitude"),
                Latitude = worksheet.Double("FSXLatitude"),
                Longitude = worksheet.Double("FSXLongitude"),
                MaxAirspeedIndicated = worksheet.Double("FSXMaxAirspeedIndicated"),
                Model = worksheet.String("FSXModel"),
                OnGround = worksheet.Bool("FSXOnGround"),
                Operator = worksheet.String("FSXOperator"),
                Registration = worksheet.String("FSXRegistration"),
                Squawk = worksheet.Int("FSXSquawk"),
                TrueHeading = worksheet.Double("FSXTrueHeading"),
                Type = worksheet.String("FSXType"),
                VerticalSpeed = worksheet.Double("FSXVerticalSpeed"),
            };
            _FlightSimulatorX.Raise(f => f.AircraftInformationReceived += null, new EventArgs<ReadAircraftInformation>(aircraftInformation));

            Assert.AreEqual(1, _FSXAircraftList.Count);
            var aircraft = _FSXAircraftList[0];
            Assert.AreEqual(worksheet.String("Icao24"), aircraft.Icao24);
            Assert.AreEqual(worksheet.Int("UniqueId"), aircraft.UniqueId);
            Assert.AreEqual(worksheet.NFloat("Latitude"), aircraft.Latitude);
            Assert.AreEqual(worksheet.NFloat("Longitude"), aircraft.Longitude);
            Assert.AreEqual(utcNow.Ticks, aircraft.DataVersion);
            Assert.AreEqual(worksheet.NFloat("GroundSpeed"), aircraft.GroundSpeed);
            Assert.AreEqual(worksheet.NFloat("Track"), aircraft.Track);
            Assert.AreEqual(worksheet.String("Type"), aircraft.Type);
            Assert.AreEqual(worksheet.String("Model"), aircraft.Model);
            Assert.AreEqual(worksheet.String("Operator"), aircraft.Operator);
            Assert.AreEqual(worksheet.String("Registration"), aircraft.Registration);
            Assert.AreEqual(worksheet.NInt("Squawk"), aircraft.Squawk);
            Assert.AreEqual(worksheet.NInt("Altitude"), aircraft.Altitude);
            Assert.AreEqual(worksheet.NInt("VerticalRate"), aircraft.VerticalRate);
        }
        public void JsonSerialiser_WriteObject_Writes_ValueTypes_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var obj = new ValueTypes() {
                BoolValue = worksheet.Bool("BoolValue"),
                UnusedBool = worksheet.Bool("UnusedBool"),
                NullableBool = worksheet.NBool("NullableBool"),
                Int = worksheet.Int("Int"),
                NullableInt = worksheet.NInt("NullableInt"),
                Long = worksheet.Long("Long"),
                NullableLong = worksheet.NLong("NullableLong"),
                Float = worksheet.Float("Float"),
                NullableFloat = worksheet.NFloat("NullableFloat"),
                Double = worksheet.Double("Double"),
                NullableDouble = worksheet.NDouble("NullableDouble"),
                DateTime = worksheet.DateTime("DateTime"),
                NullableDateTime = worksheet.NDateTime("NullableDateTime"),
            };

            _JsonSerialiser.Initialise(typeof(ValueTypes));
            _JsonSerialiser.WriteObject(_Stream, obj);

            Assert.AreEqual(worksheet.EString("Json"), GetJson());
        }
        public void CompactPositionReporting_LocalDecode_Produces_Correct_Results_For_CPR101_Tables()
        {
            // The values for this test are all taken directly from the transition latitude test tables in 1090-WP30-12 Proposed New Appendix CPR101
            var worksheet = new ExcelWorksheetData(TestContext);

            var numberOfBits = worksheet.Byte("Bits");
            var oddFormat = worksheet.Bool("OddFormat");
            var encodedLatitude = Convert.ToInt32(worksheet.String("ExpectedLatitude"), 16);
            var encodedLongitude = Convert.ToInt32(worksheet.String("ExpectedLongitude"), 16);
            var expectedLatitude = worksheet.Double("Latitude");
            var expectedLongitude = worksheet.Double("Longitude");
            var cprCoordinate = new CompactPositionReportingCoordinate(encodedLatitude, encodedLongitude, oddFormat, numberOfBits);

            // The reference latitude and longitude is set to roughly 50km of the expected latitude and longitude
            double? referenceLatitude, referenceLongitude;
            GreatCircleMaths.Destination(expectedLatitude, expectedLongitude, 45, 50, out referenceLatitude, out referenceLongitude);
            var referenceCoordinate = new GlobalCoordinate(referenceLatitude.Value, referenceLongitude.Value);

            var dataRow = worksheet.Int("DataRow"); // helps set conditional breakpoints, VSTS doesn't always process rows in ascending order as they appear in the worksheet

            var decodedCoordinate = _Cpr.LocalDecode(cprCoordinate, referenceCoordinate);

            // We need to accept 180 and -180 as being the same longitude, taking into account rounding errors
            if(expectedLongitude == -180.0 && decodedCoordinate.Longitude > 179.9999999999) expectedLongitude = 180.0;
            else if(expectedLongitude == 180.0 && decodedCoordinate.Longitude < -179.9999999999) expectedLongitude = -180.0;

            Assert.AreEqual(expectedLatitude, decodedCoordinate.Latitude, 0.0008);    // The CPR tables cover all latitudes, sometimes the rounding introduced by selecting the midpoint of a zone can be quite large
            Assert.AreEqual(expectedLongitude, decodedCoordinate.Longitude, 0.000000000001);  // This can have a lower tolerance as the CPR101 tables aren't testing longitude zone boundaries so much
        }
        public void JsonSerialiser_WriteObject_Writes_ValueTypes_Correctly_For_Non_UK_Cultures()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            foreach(var culture in new string[] { "en-US", "de-DE", "fr-FR", "ru-RU" }) {
                using(var cultureSwitcher = new CultureSwitcher(culture)) {
                    TestCleanup();
                    TestInitialise();

                    var obj = new ValueTypes() {
                        BoolValue = worksheet.Bool("BoolValue"),
                        UnusedBool = worksheet.Bool("UnusedBool"),
                        NullableBool = worksheet.NBool("NullableBool"),
                        Int = worksheet.Int("Int"),
                        NullableInt = worksheet.NInt("NullableInt"),
                        Long = worksheet.Long("Long"),
                        NullableLong = worksheet.NLong("NullableLong"),
                        Float = worksheet.Float("Float"),
                        NullableFloat = worksheet.NFloat("NullableFloat"),
                        Double = worksheet.Double("Double"),
                        NullableDouble = worksheet.NDouble("NullableDouble"),
                        DateTime = worksheet.DateTime("DateTime"),
                        NullableDateTime = worksheet.NDateTime("NullableDateTime"),
                    };

                    _JsonSerialiser.Initialise(typeof(ValueTypes));
                    _JsonSerialiser.WriteObject(_Stream, obj);

                    var message = String.Format("when culture is {0}", culture);
                    Assert.AreEqual(worksheet.EString("Json"), GetJson(), message);
                }
            }
        }