Ejemplo n.º 1
0
        public void Aircraft_UpdateCoordinates_Trims_Short_Coordinates_After_Time_Limit_Has_Passed()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var seconds  = worksheet.Int("Seconds");
            var baseTime = DateTime.UtcNow;

            for (int i = 1; i <= 3; ++i)
            {
                var secondsGapColumn = String.Format("SecondsGap{0}", i);
                var latitudeColumn   = String.Format("Latitude{0}", i);
                var longitudeColumn  = String.Format("Longitude{0}", i);
                var trackColumn      = String.Format("Track{0}", i);

                if (worksheet.String(secondsGapColumn) != null)
                {
                    var utcNow = baseTime.AddSeconds(worksheet.Int(secondsGapColumn));
                    _Aircraft.DataVersion = utcNow.Ticks;
                    _Aircraft.Latitude    = worksheet.NFloat(latitudeColumn);
                    _Aircraft.Longitude   = worksheet.NFloat(longitudeColumn);
                    _Aircraft.Track       = worksheet.NFloat(trackColumn);
                    _Aircraft.UpdateCoordinates(utcNow, seconds);
                }
            }

            Assert.AreEqual(worksheet.Int("ExpectedCount"), _Aircraft.ShortCoordinates.Count);
            for (int i = 0; i < _Aircraft.ShortCoordinates.Count; ++i)
            {
                var expectedTrackColumn = String.Format("ExpectedTrack{0}", i);
                Assert.AreEqual(worksheet.NFloat(expectedTrackColumn), _Aircraft.ShortCoordinates[i].Heading, i.ToString());
            }
        }
Ejemplo n.º 2
0
        public void ProximityGadgetAircraftJson_ToModel_Returns_The_Closest_Aircraft()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var originLatitude  = worksheet.NDouble("GadgetLat");
            var originLongitude = worksheet.NDouble("GadgetLng");

            var aircraft = CreateAircraft(2);

            for (int i = 1; i <= 2; ++i)
            {
                aircraft[i - 1].Callsign  = i.ToString();
                aircraft[i - 1].Latitude  = worksheet.NFloat(String.Format("AC{0}Lat", i));
                aircraft[i - 1].Longitude = worksheet.NFloat(String.Format("AC{0}Lng", i));
            }

            var model = ProximityGadgetAircraftJson.ToModel(aircraft, originLatitude, originLongitude);

            var closestCallsign = worksheet.String("Closest");

            if (closestCallsign == null)
            {
                Assert.IsNull(model.ClosestAircraft);
            }
            else
            {
                Assert.AreEqual(closestCallsign, model.ClosestAircraft.Callsign);
            }
        }
        public void BaseStationMessageTranslator_Translate_Translates_Messages_Correctly()
        {
            ExcelWorksheetData worksheet = new ExcelWorksheetData(TestContext);

            BaseStationMessage translated = _Implementation.Translate(worksheet.String("Text"), 123);

            Assert.AreEqual(Enum.Parse(typeof(BaseStationMessageType), worksheet.String("MessageType")), translated.MessageType);
            Assert.AreEqual(Enum.Parse(typeof(BaseStationTransmissionType), worksheet.String("TransmissionType")), translated.TransmissionType);
            Assert.AreEqual(Enum.Parse(typeof(BaseStationStatusCode), worksheet.String("StatusCode")), translated.StatusCode);
            Assert.AreEqual(worksheet.Int("SessionId"), translated.SessionId);
            Assert.AreEqual(worksheet.Int("AircraftId"), translated.AircraftId);
            Assert.AreEqual(worksheet.String("Icao24"), translated.Icao24);
            Assert.AreEqual(worksheet.Int("FlightId"), translated.FlightId);
            Assert.AreEqual(worksheet.DateTime("MessageGenerated"), translated.MessageGenerated);
            Assert.AreEqual(worksheet.DateTime("MessageLogged"), translated.MessageLogged);
            Assert.AreEqual(worksheet.String("Callsign"), translated.Callsign);
            Assert.AreEqual(worksheet.NFloat("Altitude"), translated.Altitude);
            Assert.AreEqual(worksheet.NFloat("GroundSpeed"), translated.GroundSpeed);
            Assert.AreEqual(worksheet.NFloat("Track"), translated.Track);
            Assert.AreEqual(worksheet.NDouble("Latitude"), translated.Latitude);
            Assert.AreEqual(worksheet.NDouble("Longitude"), translated.Longitude);
            Assert.AreEqual(worksheet.NFloat("VerticalRate"), translated.VerticalRate);
            Assert.AreEqual(worksheet.NInt("Squawk"), translated.Squawk);
            Assert.AreEqual(worksheet.NBool("SquawkHasChanged"), translated.SquawkHasChanged);
            Assert.AreEqual(worksheet.NBool("Emergency"), translated.Emergency);
            Assert.AreEqual(worksheet.NBool("IdentActive"), translated.IdentActive);
            Assert.AreEqual(worksheet.NBool("OnGround"), translated.OnGround);
            Assert.AreEqual(worksheet.Bool("IsMlat"), translated.IsMlat);
        }
Ejemplo n.º 4
0
        private void Do_BaseStationMessage_ToBaseStationString_Builds_Valid_BaseStation_Messages_From_A_BaseStationMessage_Object()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Implementation.MessageType      = worksheet.ParseEnum <BaseStationMessageType>("MessageType");
            _Implementation.TransmissionType = worksheet.ParseEnum <BaseStationTransmissionType>("TransmissionType");
            _Implementation.StatusCode       = worksheet.ParseEnum <BaseStationStatusCode>("StatusCode");
            _Implementation.SessionId        = worksheet.Int("SessionId");
            _Implementation.AircraftId       = worksheet.Int("AircraftId");
            _Implementation.Icao24           = worksheet.String("Icao24");
            _Implementation.FlightId         = worksheet.Int("FlightId");
            _Implementation.MessageGenerated = worksheet.DateTime("MessageGenerated");
            _Implementation.MessageLogged    = worksheet.DateTime("MessageLogged");
            _Implementation.Callsign         = worksheet.String("Callsign");
            _Implementation.Altitude         = worksheet.NInt("Altitude");
            _Implementation.GroundSpeed      = worksheet.NFloat("GroundSpeed");
            _Implementation.Track            = worksheet.NFloat("Track");
            _Implementation.Latitude         = worksheet.NDouble("Latitude");
            _Implementation.Longitude        = worksheet.NDouble("Longitude");
            _Implementation.VerticalRate     = worksheet.NInt("VerticalRate");
            _Implementation.Squawk           = worksheet.NInt("Squawk");
            _Implementation.SquawkHasChanged = worksheet.NBool("SquawkHasChanged");
            _Implementation.Emergency        = worksheet.NBool("Emergency");
            _Implementation.IdentActive      = worksheet.NBool("IdentActive");
            _Implementation.OnGround         = worksheet.NBool("OnGround");

            Assert.AreEqual(worksheet.String("Text"), _Implementation.ToBaseStationString());
        }
        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 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);
                }
            }
        }
Ejemplo n.º 7
0
        public void ProximityGadgetClosestAircraftJson_ToModel_Fills_Calculated_Details_Correctly()
        {
            var worksheet       = new ExcelWorksheetData(TestContext);
            var originLatitude  = worksheet.NDouble("GadgetLat");
            var originLongitude = worksheet.NDouble("GadgetLng");

            var aircraft = TestUtilities.CreateMockInstance <IAircraft>();

            bool hasPosition = worksheet.String("AircraftLat") != null;

            if (hasPosition)
            {
                aircraft.Object.Latitude  = worksheet.NFloat("AircraftLat");
                aircraft.Object.Longitude = worksheet.NFloat("AircraftLng");
            }

            var model = ProximityGadgetClosestAircraftJson.ToModel(aircraft.Object, originLatitude, originLongitude);

            Assert.AreEqual(worksheet.EString("Bearing"), model.BearingFromHere);
            Assert.AreEqual(worksheet.EString("Distance"), model.DistanceFromHere);
        }
Ejemplo n.º 8
0
        public void Aircraft_UpdateCoordinates_Replaces_Last_Full_Coordinate_If_Track_Hardly_Changes()
        {
            // If an update changes the position but the aircraft remains on the same ground track as the previous position
            // then there's no need to keep the previous position, it can be replaced with the current one.

            var worksheet = new ExcelWorksheetData(TestContext);

            var time = DateTime.Now;

            var expected = new List <Coordinate>();

            for (int i = 1; i <= 4; ++i)
            {
                var latInColumn = String.Format("Lat{0}", i);
                var lngInColumn = String.Format("Lng{0}", i);
                var trkInColumn = String.Format("Trk{0}", i);

                var latOutColumn = String.Format("CLat{0}", i);
                var lngOutColumn = String.Format("CLng{0}", i);
                var trkOutColumn = String.Format("CTrk{0}", i);

                if (worksheet.String(latInColumn) != null)
                {
                    time = time.AddHours(1);
                    _Aircraft.DataVersion = time.Ticks;
                    _Aircraft.Latitude    = worksheet.Float(latInColumn);
                    _Aircraft.Longitude   = worksheet.Float(lngInColumn);
                    _Aircraft.Track       = worksheet.NFloat(trkInColumn);
                    _Aircraft.UpdateCoordinates(time, 300 * 60 * 60);

                    Assert.AreEqual(i, _Aircraft.ShortCoordinates.Count);
                }

                if (worksheet.String(latOutColumn) != null)
                {
                    expected.Add(new Coordinate(0, 0, worksheet.Float(latOutColumn), worksheet.Float(lngOutColumn), worksheet.NFloat(trkOutColumn)));
                }
            }

            Assert.AreEqual(expected.Count, _Aircraft.FullCoordinates.Count);

            for (int i = 0; i < expected.Count; ++i)
            {
                var expCoordinate  = expected[i];
                var fullCoordinate = _Aircraft.FullCoordinates[i];

                Assert.AreEqual(expCoordinate, fullCoordinate, i.ToString());
                Assert.AreEqual(expCoordinate.Heading, fullCoordinate.Heading, i.ToString());
            }
        }
        public void Aircraft_UpdateCoordinates_Replaces_Last_Full_Coordinate_If_Track_Hardly_Changes()
        {
            // If an update changes the position but the aircraft remains on the same ground track as the previous position
            // then there's no need to keep the previous position, it can be replaced with the current one.

            var worksheet = new ExcelWorksheetData(TestContext);

            var time = DateTime.Now;

            var expected = new List<Coordinate>();
            for(int i = 1;i <= 4;++i) {
                var latInColumn = String.Format("Lat{0}", i);
                var lngInColumn = String.Format("Lng{0}", i);
                var trkInColumn = String.Format("Trk{0}", i);

                var latOutColumn = String.Format("CLat{0}", i);
                var lngOutColumn = String.Format("CLng{0}", i);
                var trkOutColumn = String.Format("CTrk{0}", i);

                if(worksheet.String(latInColumn) != null) {
                    time = time.AddHours(1);
                    _Aircraft.DataVersion = time.Ticks;
                    _Aircraft.Latitude = worksheet.Float(latInColumn);
                    _Aircraft.Longitude = worksheet.Float(lngInColumn);
                    _Aircraft.Track = worksheet.NFloat(trkInColumn);
                    _Aircraft.UpdateCoordinates(time, 300 * 60 * 60);

                    Assert.AreEqual(i, _Aircraft.ShortCoordinates.Count);
                }

                if(worksheet.String(latOutColumn) != null) {
                    expected.Add(new Coordinate(0, 0, worksheet.Float(latOutColumn), worksheet.Float(lngOutColumn), worksheet.NFloat(trkOutColumn)));
                }
            }

            Assert.AreEqual(expected.Count, _Aircraft.FullCoordinates.Count);

            for(int i = 0;i < expected.Count;++i) {
                var expCoordinate = expected[i];
                var fullCoordinate = _Aircraft.FullCoordinates[i];

                Assert.AreEqual(expCoordinate, fullCoordinate, i.ToString());
                Assert.AreEqual(expCoordinate.Heading, fullCoordinate.Heading, i.ToString());
            }
        }
        public void Aircraft_UpdateCoordinates_Trims_Short_Coordinates_After_Time_Limit_Has_Passed()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var seconds = worksheet.Int("Seconds");
            var baseTime = DateTime.UtcNow;

            for(int i = 1;i <= 3;++i) {
                var secondsGapColumn = String.Format("SecondsGap{0}", i);
                var latitudeColumn = String.Format("Latitude{0}", i);
                var longitudeColumn = String.Format("Longitude{0}", i);
                var trackColumn = String.Format("Track{0}", i);

                if(worksheet.String(secondsGapColumn) != null) {
                    var utcNow = baseTime.AddSeconds(worksheet.Int(secondsGapColumn));
                    _Aircraft.DataVersion = utcNow.Ticks;
                    _Aircraft.Latitude = worksheet.NFloat(latitudeColumn);
                    _Aircraft.Longitude = worksheet.NFloat(longitudeColumn);
                    _Aircraft.Track = worksheet.NFloat(trackColumn);
                    _Aircraft.UpdateCoordinates(utcNow, seconds);
                }
            }

            Assert.AreEqual(worksheet.Int("ExpectedCount"), _Aircraft.ShortCoordinates.Count);
            for(int i = 0;i < _Aircraft.ShortCoordinates.Count;++i) {
                var expectedTrackColumn = String.Format("ExpectedTrack{0}", i);
                Assert.AreEqual(worksheet.NFloat(expectedTrackColumn), _Aircraft.ShortCoordinates[i].Heading, i.ToString());
            }
        }
        private void Do_BaseStationMessage_ToBaseStationString_Builds_Valid_BaseStation_Messages_From_A_BaseStationMessage_Object()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Implementation.MessageType = worksheet.ParseEnum<BaseStationMessageType>("MessageType");
            _Implementation.TransmissionType = worksheet.ParseEnum<BaseStationTransmissionType>("TransmissionType");
            _Implementation.StatusCode = worksheet.ParseEnum<BaseStationStatusCode>("StatusCode");
            _Implementation.SessionId = worksheet.Int("SessionId");
            _Implementation.AircraftId = worksheet.Int("AircraftId");
            _Implementation.Icao24 = worksheet.String("Icao24");
            _Implementation.FlightId = worksheet.Int("FlightId");
            _Implementation.MessageGenerated = worksheet.DateTime("MessageGenerated");
            _Implementation.MessageLogged = worksheet.DateTime("MessageLogged");
            _Implementation.Callsign = worksheet.String("Callsign");
            _Implementation.Altitude = worksheet.NInt("Altitude");
            _Implementation.GroundSpeed = worksheet.NFloat("GroundSpeed");
            _Implementation.Track = worksheet.NFloat("Track");
            _Implementation.Latitude = worksheet.NDouble("Latitude");
            _Implementation.Longitude = worksheet.NDouble("Longitude");
            _Implementation.VerticalRate = worksheet.NInt("VerticalRate");
            _Implementation.Squawk = worksheet.NInt("Squawk");
            _Implementation.SquawkHasChanged = worksheet.NBool("SquawkHasChanged");
            _Implementation.Emergency = worksheet.NBool("Emergency");
            _Implementation.IdentActive = worksheet.NBool("IdentActive");
            _Implementation.OnGround = worksheet.NBool("OnGround");

            Assert.AreEqual(worksheet.String("Text"), _Implementation.ToBaseStationString());
        }
Ejemplo n.º 12
0
        public void Plugin_Flight_Updates_Message_Counters_Correctly()
        {
            // These are the nullable integers which start with "Num"
            var worksheet = new ExcelWorksheetData(TestContext);

            SetEnabledOption(true);

            BaseStationFlight flight = null;
            _BaseStationDatabase.Setup(d => d.UpdateFlight(It.IsAny<BaseStationFlight>())).Callback((BaseStationFlight f) => { flight = f; });

            _Plugin.Startup(_StartupParameters);

            var message = new BaseStationMessage() {
                Icao24 = "Z",
                MessageType = worksheet.ParseEnum<BaseStationMessageType>("MessageType"),
                TransmissionType = worksheet.ParseEnum<BaseStationTransmissionType>("TransmissionType"),
                StatusCode = worksheet.ParseEnum<BaseStationStatusCode>("StatusCode"),
                GroundSpeed = worksheet.NFloat("GroundSpeed"),
                Track = worksheet.NFloat("Track"),
                Latitude = worksheet.NFloat("Latitude"),
                Longitude = worksheet.NFloat("Longitude"),
                VerticalRate = worksheet.NInt("VerticalRate"),
            };
            _Listener.Raise(r => r.Port30003MessageReceived += null, new BaseStationMessageEventArgs(message));

            SetProviderTimes(_Provider.Object.LocalNow.AddMinutes(MinutesBeforeFlightClosed));
            _HeartbeatService.Raise(s => s.SlowTick += null, EventArgs.Empty);

            _BaseStationDatabase.Verify(d => d.UpdateFlight(It.IsAny<BaseStationFlight>()), Times.Once());

            // Note that the totals are not null after the final update even if no messages were received in a particular category
            Assert.AreEqual(worksheet.Int("NumPosMsgRec"), flight.NumPosMsgRec.Value);
            Assert.AreEqual(worksheet.Int("NumADSBMsgRec"), flight.NumADSBMsgRec.Value);
            Assert.AreEqual(worksheet.Int("NumModeSMsgRec"), flight.NumModeSMsgRec.Value);
            Assert.AreEqual(worksheet.Int("NumIDMsgRec"), flight.NumIDMsgRec.Value);
            Assert.AreEqual(worksheet.Int("NumSurPosMsgRec"), flight.NumSurPosMsgRec.Value);
            Assert.AreEqual(worksheet.Int("NumAirPosMsgRec"), flight.NumAirPosMsgRec.Value);
            Assert.AreEqual(worksheet.Int("NumAirVelMsgRec"), flight.NumAirVelMsgRec.Value);
            Assert.AreEqual(worksheet.Int("NumSurAltMsgRec"), flight.NumSurAltMsgRec.Value);
            Assert.AreEqual(worksheet.Int("NumSurIDMsgRec"), flight.NumSurIDMsgRec.Value);
            Assert.AreEqual(worksheet.Int("NumAirToAirMsgRec"), flight.NumAirToAirMsgRec.Value);
            Assert.AreEqual(worksheet.Int("NumAirCallRepMsgRec"), flight.NumAirCallRepMsgRec.Value);
        }
        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 BaseStationMessageCompressor_Compress_And_Decompress_Work_As_Expected()
        {
            ExcelWorksheetData worksheet = new ExcelWorksheetData(TestContext);

            var messageIn = new BaseStationMessage();

            messageIn.MessageType      = worksheet.ParseEnum <BaseStationMessageType>("MessageType");
            messageIn.TransmissionType = worksheet.ParseEnum <BaseStationTransmissionType>("TransmissionType");
            messageIn.StatusCode       = worksheet.ParseEnum <BaseStationStatusCode>("StatusCode");
            messageIn.Icao24           = worksheet.EString("Icao24");
            messageIn.SessionId        = worksheet.Int("SessionId");
            messageIn.AircraftId       = worksheet.Int("AircraftId");
            messageIn.FlightId         = worksheet.Int("FlightId");
            messageIn.MessageGenerated = worksheet.DateTime("MessageGenerated");
            messageIn.MessageLogged    = worksheet.DateTime("MessageLogged");
            messageIn.Callsign         = worksheet.String("Callsign");
            messageIn.Altitude         = worksheet.NInt("Altitude");
            messageIn.GroundSpeed      = worksheet.NInt("GroundSpeed");
            messageIn.Track            = worksheet.NFloat("Track");
            messageIn.Latitude         = worksheet.NDouble("Latitude");
            messageIn.Longitude        = worksheet.NDouble("Longitude");
            messageIn.VerticalRate     = worksheet.NInt("VerticalRate");
            messageIn.Squawk           = worksheet.NInt("Squawk");
            messageIn.SquawkHasChanged = worksheet.NBool("SquawkHasChanged");
            messageIn.Emergency        = worksheet.NBool("Emergency");
            messageIn.IdentActive      = worksheet.NBool("IdentActive");
            messageIn.OnGround         = worksheet.NBool("OnGround");

            int expectedLength = worksheet.Int("Length");

            byte[] bytes = _Compressor.Compress(messageIn);
            Assert.AreEqual(expectedLength, bytes.Length);

            DateTime           earliestDate = DateTime.Now;
            BaseStationMessage messageOut   = _Compressor.Decompress(bytes);
            DateTime           latestDate   = DateTime.Now;

            if (bytes.Length == 0)
            {
                Assert.IsNull(messageOut);
            }
            else
            {
                Assert.AreEqual(messageIn.MessageType, messageOut.MessageType);
                Assert.AreEqual(messageIn.TransmissionType, messageOut.TransmissionType);
                Assert.AreEqual(BaseStationStatusCode.None, messageOut.StatusCode);
                Assert.AreEqual(messageIn.Icao24, messageOut.Icao24);
                Assert.AreEqual(0, messageOut.SessionId);
                Assert.AreEqual(0, messageOut.AircraftId);
                Assert.AreEqual(0, messageOut.FlightId);
                Assert.AreEqual((double)earliestDate.Ticks, (double)messageOut.MessageGenerated.Ticks, (double)latestDate.Ticks - (double)earliestDate.Ticks);
                Assert.AreEqual((double)earliestDate.Ticks, (double)messageOut.MessageLogged.Ticks, (double)latestDate.Ticks - (double)earliestDate.Ticks);
                Assert.AreEqual(messageIn.Callsign, messageOut.Callsign);
                Assert.AreEqual(messageIn.Altitude, messageOut.Altitude);
                Assert.AreEqual(messageIn.GroundSpeed, messageOut.GroundSpeed);
                Assert.AreEqual(messageIn.Track, messageOut.Track);
                if (messageIn.Latitude == null)
                {
                    Assert.IsNull(messageOut.Latitude);
                }
                else
                {
                    Assert.AreEqual(messageIn.Latitude.Value, messageOut.Latitude.Value, 0.000001);
                }
                if (messageIn.Longitude == null)
                {
                    Assert.IsNull(messageOut.Longitude);
                }
                else
                {
                    Assert.AreEqual(messageIn.Longitude.Value, messageOut.Longitude.Value, 0.000001);
                }
                Assert.AreEqual(messageIn.VerticalRate, messageOut.VerticalRate);
                Assert.AreEqual(messageIn.Squawk, messageOut.Squawk);
                Assert.AreEqual(messageIn.SquawkHasChanged, messageOut.SquawkHasChanged);
                Assert.AreEqual(messageIn.Emergency, messageOut.Emergency);
                Assert.AreEqual(messageIn.IdentActive, messageOut.IdentActive);
                Assert.AreEqual(messageIn.OnGround, messageOut.OnGround);
            }
        }
        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 WebSite_BaseStationAircraftList_Calculates_Distances_From_Browser_To_Aircraft_Correctly_When_Culture_Is_Not_UK()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            using(var switcher = new CultureSwitcher("de-DE")) {
                var aircraft = new Mock<IAircraft>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties();
                _BaseStationAircraft.Add(aircraft.Object);

                aircraft.Object.Latitude = worksheet.NFloat("AircraftLatitude");
                aircraft.Object.Longitude = worksheet.NFloat("AircraftLongitude");

                string address = String.Format("{0}?lat={1}&lng={2}", _AircraftListAddress.Page, worksheet.String("BrowserLatitude"), worksheet.String("BrowserLongitude"));

                var list = SendJsonRequest<AircraftListJson>(address);
                Assert.AreEqual(1, list.Aircraft.Count);
                var aircraftJson = list.Aircraft[0];

                double? expected = worksheet.NDouble("Distance");
                if(expected == null) Assert.IsNull(aircraftJson.DistanceFromHere);
                else Assert.AreEqual((double)expected, (double)aircraftJson.DistanceFromHere);
            }
        }
        public void BaseStationMessageCompressor_Compress_And_Decompress_Work_As_Expected()
        {
            ExcelWorksheetData worksheet = new ExcelWorksheetData(TestContext);

            var messageIn = new BaseStationMessage();
            messageIn.MessageType = worksheet.ParseEnum<BaseStationMessageType>("MessageType");
            messageIn.TransmissionType = worksheet.ParseEnum<BaseStationTransmissionType>("TransmissionType");
            messageIn.StatusCode = worksheet.ParseEnum<BaseStationStatusCode>("StatusCode");
            messageIn.Icao24 = worksheet.EString("Icao24");
            messageIn.SessionId = worksheet.Int("SessionId");
            messageIn.AircraftId = worksheet.Int("AircraftId");
            messageIn.FlightId = worksheet.Int("FlightId");
            messageIn.MessageGenerated = worksheet.DateTime("MessageGenerated");
            messageIn.MessageLogged = worksheet.DateTime("MessageLogged");
            messageIn.Callsign = worksheet.String("Callsign");
            messageIn.Altitude = worksheet.NInt("Altitude");
            messageIn.GroundSpeed = worksheet.NInt("GroundSpeed");
            messageIn.Track = worksheet.NFloat("Track");
            messageIn.Latitude = worksheet.NDouble("Latitude");
            messageIn.Longitude = worksheet.NDouble("Longitude");
            messageIn.VerticalRate = worksheet.NInt("VerticalRate");
            messageIn.Squawk = worksheet.NInt("Squawk");
            messageIn.SquawkHasChanged = worksheet.NBool("SquawkHasChanged");
            messageIn.Emergency = worksheet.NBool("Emergency");
            messageIn.IdentActive = worksheet.NBool("IdentActive");
            messageIn.OnGround = worksheet.NBool("OnGround");

            int expectedLength = worksheet.Int("Length");

            byte[] bytes = _Compressor.Compress(messageIn);
            Assert.AreEqual(expectedLength, bytes.Length);

            DateTime earliestDate = DateTime.Now;
            BaseStationMessage messageOut = _Compressor.Decompress(bytes);
            DateTime latestDate = DateTime.Now;

            if(bytes.Length == 0) Assert.IsNull(messageOut);
            else {
                Assert.AreEqual(messageIn.MessageType, messageOut.MessageType);
                Assert.AreEqual(messageIn.TransmissionType, messageOut.TransmissionType);
                Assert.AreEqual(BaseStationStatusCode.None, messageOut.StatusCode);
                Assert.AreEqual(messageIn.Icao24, messageOut.Icao24);
                Assert.AreEqual(0, messageOut.SessionId);
                Assert.AreEqual(0, messageOut.AircraftId);
                Assert.AreEqual(0, messageOut.FlightId);
                Assert.AreEqual((double)earliestDate.Ticks, (double)messageOut.MessageGenerated.Ticks, (double)latestDate.Ticks - (double)earliestDate.Ticks);
                Assert.AreEqual((double)earliestDate.Ticks, (double)messageOut.MessageLogged.Ticks, (double)latestDate.Ticks - (double)earliestDate.Ticks);
                Assert.AreEqual(messageIn.Callsign, messageOut.Callsign);
                Assert.AreEqual(messageIn.Altitude, messageOut.Altitude);
                Assert.AreEqual(messageIn.GroundSpeed, messageOut.GroundSpeed);
                Assert.AreEqual(messageIn.Track, messageOut.Track);
                if(messageIn.Latitude == null) Assert.IsNull(messageOut.Latitude);
                else Assert.AreEqual(messageIn.Latitude.Value, messageOut.Latitude.Value, 0.000001);
                if(messageIn.Longitude == null) Assert.IsNull(messageOut.Longitude);
                else Assert.AreEqual(messageIn.Longitude.Value, messageOut.Longitude.Value, 0.000001);
                Assert.AreEqual(messageIn.VerticalRate, messageOut.VerticalRate);
                Assert.AreEqual(messageIn.Squawk, messageOut.Squawk);
                Assert.AreEqual(messageIn.SquawkHasChanged, messageOut.SquawkHasChanged);
                Assert.AreEqual(messageIn.Emergency, messageOut.Emergency);
                Assert.AreEqual(messageIn.IdentActive, messageOut.IdentActive);
                Assert.AreEqual(messageIn.OnGround, messageOut.OnGround);
            }
        }
        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 WebSite_BaseStationAircraftList_AircraftListFilter_Distance_AircraftListFiltered_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _AircraftListAddress.Filter = _AircraftListFilter;
            _AircraftListAddress.BrowserLatitude = worksheet.Float("BrowserLatitude");
            _AircraftListAddress.BrowserLongitude = worksheet.Float("BrowserLongitude");

            AddBlankAircraft(1);
            _BaseStationAircraft[0].Latitude = worksheet.NFloat("AircraftLatitude");
            _BaseStationAircraft[0].Longitude = worksheet.NFloat("AircraftLongitude");

            _AircraftListFilter.DistanceLower = worksheet.NDouble("DistanceLower");
            _AircraftListFilter.DistanceUpper = worksheet.NDouble("DistanceUpper");

            bool passed = SendJsonRequest<AircraftListJson>(_AircraftListAddress.Address).Aircraft.Count == 1;

            Assert.AreEqual(worksheet.Bool("Passes"), passed);
        }
        public void WebSite_BaseStationAircraftList_AircraftListFilter_PositionWithin_Works_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _AircraftListAddress.Filter = _AircraftListFilter;

            AddBlankAircraft(1);
            _BaseStationAircraft[0].Latitude = worksheet.NFloat("Latitude");
            _BaseStationAircraft[0].Longitude = worksheet.NFloat("Longitude");

            _AircraftListFilter.PositionWithin = new Pair<Coordinate>(
                new Coordinate(worksheet.Float("Top"), worksheet.Float("Left")),
                new Coordinate(worksheet.Float("Bottom"), worksheet.Float("Right"))
            );

            var list = SendJsonRequest<AircraftListJson>(_AircraftListAddress.Address);

            Assert.AreEqual(worksheet.Bool("IsInBounds") ? 1 : 0, list.Aircraft.Count);
        }
        public void WebSite_BaseStationAircraftList_Builds_Arrays_Of_Trail_Coordinates_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            AddBlankAircraft(1);
            var aircraft = _BaseStationAircraft[0];
            Mock<IAircraft> mockAircraft = Mock.Get(aircraft);

            aircraft.Latitude = worksheet.NFloat("ACLat");
            aircraft.Longitude = worksheet.NFloat("ACLng");
            aircraft.Track = worksheet.NFloat("ACTrk");
            aircraft.FirstCoordinateChanged = worksheet.Long("ACFirstCoCh");
            aircraft.LastCoordinateChanged = worksheet.Long("ACLastCoCh");
            aircraft.PositionTime = new DateTime(1970, 1, 1, 0, 0, 0, worksheet.Int("ACPosTimeCh"));
            mockAircraft.Setup(m => m.PositionTimeChanged).Returns(worksheet.Long("ACPosTimeCh"));

            for(int i = 1;i <= 2;++i) {
                var dataVersion = String.Format("Coord{0}DV", i);
                var tick = String.Format("Coord{0}Tick", i);
                var latitude = String.Format("Coord{0}Lat", i);
                var longitude = String.Format("Coord{0}Lng", i);
                var track = String.Format("Coord{0}Trk", i);
                if(worksheet.String(dataVersion) != null) {
                    DateTime dotNetDate = new DateTime(1970, 1, 1, 0, 0, 0, worksheet.Int(tick));
                    var coordinate = new Coordinate(worksheet.Long(dataVersion), dotNetDate.Ticks, worksheet.Float(latitude), worksheet.Float(longitude), worksheet.NFloat(track));
                    aircraft.FullCoordinates.Add(coordinate);
                    aircraft.ShortCoordinates.Add(coordinate);
                }
            }

            _AircraftListAddress.PreviousDataVersion = worksheet.Long("ArgsPrevDV");
            if(worksheet.Bool("ArgsIsPrevAC")) _AircraftListAddress.PreviousAircraft.Add(0);
            _AircraftListAddress.ShowShortTrail = worksheet.Bool("ArgsShort");
            _AircraftListAddress.ResendTrails = worksheet.Bool("ArgsResend");

            var aircraftJson = SendJsonRequest<AircraftListJson>(_AircraftListAddress.Address).Aircraft[0];

            var count = worksheet.Int("Count");
            if(count == 0) {
                Assert.IsNull(aircraftJson.ShortCoordinates);
                Assert.IsNull(aircraftJson.FullCoordinates);
            } else {
                var list = worksheet.Bool("IsShort") ? aircraftJson.ShortCoordinates : aircraftJson.FullCoordinates;
                Assert.AreEqual(count, list.Count);
                for(int i = 0;i < count;++i) {
                    var column = String.Format("R{0}", i);
                    Assert.AreEqual(worksheet.NDouble(column), list[i], "Element {0}", i);
                }
            }

            Assert.AreEqual(worksheet.Bool("ResetTrail"), aircraftJson.ResetTrail);
        }
        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 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 BaseStationMessageTranslator_Translate_Translates_Messages_Correctly()
        {
            ExcelWorksheetData worksheet = new ExcelWorksheetData(TestContext);

            BaseStationMessage translated = _Implementation.Translate(worksheet.String("Text"));
            Assert.AreEqual(Enum.Parse(typeof(BaseStationMessageType), worksheet.String("MessageType")), translated.MessageType);
            Assert.AreEqual(Enum.Parse(typeof(BaseStationTransmissionType), worksheet.String("TransmissionType")), translated.TransmissionType);
            Assert.AreEqual(Enum.Parse(typeof(BaseStationStatusCode), worksheet.String("StatusCode")), translated.StatusCode);
            Assert.AreEqual(worksheet.Int("SessionId"), translated.SessionId);
            Assert.AreEqual(worksheet.Int("AircraftId"), translated.AircraftId);
            Assert.AreEqual(worksheet.String("Icao24"), translated.Icao24);
            Assert.AreEqual(worksheet.Int("FlightId"), translated.FlightId);
            Assert.AreEqual(worksheet.DateTime("MessageGenerated"), translated.MessageGenerated);
            Assert.AreEqual(worksheet.DateTime("MessageLogged"), translated.MessageLogged);
            Assert.AreEqual(worksheet.String("Callsign"), translated.Callsign);
            Assert.AreEqual(worksheet.NFloat("Altitude"), translated.Altitude);
            Assert.AreEqual(worksheet.NFloat("GroundSpeed"), translated.GroundSpeed);
            Assert.AreEqual(worksheet.NFloat("Track"), translated.Track);
            Assert.AreEqual(worksheet.NDouble("Latitude"), translated.Latitude);
            Assert.AreEqual(worksheet.NDouble("Longitude"), translated.Longitude);
            Assert.AreEqual(worksheet.NFloat("VerticalRate"), translated.VerticalRate);
            Assert.AreEqual(worksheet.NInt("Squawk"), translated.Squawk);
            Assert.AreEqual(worksheet.NBool("SquawkHasChanged"), translated.SquawkHasChanged);
            Assert.AreEqual(worksheet.NBool("Emergency"), translated.Emergency);
            Assert.AreEqual(worksheet.NBool("IdentActive"), translated.IdentActive);
            Assert.AreEqual(worksheet.NBool("OnGround"), translated.OnGround);
        }
        public void WebSite_BaseStationAircraftList_Calculates_Distances_From_Browser_To_Aircraft_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var aircraft = new Mock<IAircraft>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties();
            _BaseStationAircraft.Add(aircraft.Object);

            aircraft.Object.Latitude = worksheet.NFloat("AircraftLatitude");
            aircraft.Object.Longitude = worksheet.NFloat("AircraftLongitude");

            _AircraftListAddress.BrowserLatitude = worksheet.NDouble("BrowserLatitude");
            _AircraftListAddress.BrowserLongitude = worksheet.NDouble("BrowserLongitude");

            var list = SendJsonRequest<AircraftListJson>(_AircraftListAddress.Address);
            Assert.AreEqual(1, list.Aircraft.Count);
            var aircraftJson = list.Aircraft[0];

            double? expected = worksheet.NDouble("Distance");
            if(expected == null) Assert.IsNull(aircraftJson.DistanceFromHere);
            else Assert.AreEqual((double)expected, (double)aircraftJson.DistanceFromHere);
        }