public void PluginSettingsStorage_Save_Translates_Key_Values_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var settings = new PluginSettings();

            for (int i = 1; i <= worksheet.Int("Count"); ++i)
            {
                var key   = worksheet.EString(String.Format("Key{0}", i));
                var value = worksheet.EString(String.Format("Value{0}", i));
                if (value != null)
                {
                    value = value.Replace(@"\n", "\n").Replace(@"\r", "\r");
                }
                settings.Values.Add(key, value);
            }

            _Provider.Setup(p => p.FileWriteAllLines(It.IsAny <string>(), It.IsAny <string[]>())).Callback((string fileName, string[] lines) => {
                Assert.AreEqual(worksheet.Int("LineCount"), lines.Length);
                for (int i = 1; i <= worksheet.Int("LineCount"); ++i)
                {
                    Assert.AreEqual(worksheet.EString(String.Format("Line{0}", i)), lines[i - 1]);
                }
            });

            _Storage.Save(settings);
            _Provider.Verify(p => p.FileWriteAllLines(It.IsAny <string>(), It.IsAny <string[]>()), Times.Once());
        }
Exemple #2
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 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);
        }
Exemple #4
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());
            }
        }
        public void ModeSParity_StripParity_Removes_Parity_From_Last_Three_Bytes()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var bytes = worksheet.Bytes("Bytes");
            var offset = worksheet.Int("Offset");
            var length = worksheet.Int("Length");

            _ModeSParity.StripParity(bytes, offset, length);

            Assert.IsTrue(worksheet.Bytes("Expected").SequenceEqual(bytes));
        }
Exemple #6
0
        public void ModeSParity_StripParity_Removes_Parity_From_Last_Three_Bytes()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var bytes  = worksheet.Bytes("Bytes");
            var offset = worksheet.Int("Offset");
            var length = worksheet.Int("Length");

            _ModeSParity.StripParity(bytes, offset, length);

            Assert.IsTrue(worksheet.Bytes("Expected").SequenceEqual(bytes));
        }
Exemple #7
0
        public void RequestReceivedEventArgs_Constructor_Builds_Properties_From_Request_Correctly()
        {
            ExcelWorksheetData worksheet = new ExcelWorksheetData(TestContext);

            var request = new Mock <IRequest>()
            {
                DefaultValue = DefaultValue.Mock
            }.SetupAllProperties();
            var response = new Mock <IResponse>()
            {
                DefaultValue = DefaultValue.Mock
            }.SetupAllProperties();
            var headers = new NameValueCollection();

            var endPoint = new IPEndPoint(IPAddress.Parse(worksheet.String("ResponseAddress")), 45678);

            request.Setup(r => r.RemoteEndPoint).Returns(endPoint);
            request.Setup(r => r.Url).Returns(new Uri(worksheet.EString("Url")));
            request.Setup(r => r.RawUrl).Returns(worksheet.EString("RawUrl"));
            request.Setup(r => r.Headers).Returns(headers);

            var xForwardedFor = worksheet.EString("XForwardedFor");

            if (xForwardedFor != null)
            {
                headers.Add("X-Forwarded-For", xForwardedFor);
            }

            var args = new RequestReceivedEventArgs(request.Object, response.Object, worksheet.EString("Root"));

            Assert.AreEqual(worksheet.EString("WebSite"), args.WebSite);
            Assert.AreEqual(worksheet.EString("PathAndFile"), args.PathAndFile);
            Assert.AreEqual(worksheet.EString("Path"), args.Path);
            Assert.AreEqual(worksheet.EString("File"), args.File);
            Assert.AreEqual(worksheet.EString("ProxyAddress"), args.ProxyAddress);
            Assert.AreEqual(worksheet.EString("ClientAddress"), args.ClientAddress);
            Assert.AreEqual(worksheet.Bool("IsInternetRequest"), args.IsInternetRequest);
            Assert.AreEqual(worksheet.Int("PathCount"), args.PathParts.Count);
            Assert.AreEqual(worksheet.Int("QueryCount"), args.QueryString.Count);

            for (var i = 0; i < args.PathParts.Count; ++i)
            {
                Assert.AreEqual(worksheet.EString(String.Format("Path{0}", i)), args.PathParts[i]);
            }

            for (var i = 0; i < args.QueryString.Count; ++i)
            {
                var expectedName  = worksheet.String(String.Format("QueryName{0}", i));
                var expectedValue = worksheet.String(String.Format("QueryValue{0}", i));

                Assert.AreEqual(expectedValue, args.QueryString[expectedName]);
            }
        }
        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 AirPressureLookup_FindClosest_Returns_Correct_AirPressure_Record()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            for (var i = 1; i <= 3; ++i)
            {
                var latitudeColumn  = String.Format("Lat{0}", i);
                var longitudeColumn = String.Format("Lng{0}", i);
                if (worksheet.String(latitudeColumn) != null)
                {
                    _AirPressures.Add(new AirPressure()
                    {
                        Latitude   = worksheet.Float(latitudeColumn),
                        Longitude  = worksheet.Float(longitudeColumn),
                        AgeSeconds = (short)i,
                    });
                }
            }
            _Lookup.LoadAirPressures(_AirPressures, _Now);

            var expected = worksheet.Int("Closest");
            var actual   = _Lookup.FindClosest(worksheet.Float("Lat"), worksheet.Float("Lng"));

            Assert.AreEqual(expected, actual.AgeSeconds);
        }
        public void ConnectionSessionLogPresenter_Clicking_ShowSessions_Triggers_Validation()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Presenter.Initialise(_View.Object);
            _View.Object.StartDate = worksheet.DateTime("StartDate");
            _View.Object.EndDate   = worksheet.DateTime("EndDate");

            ValidationResults validationResults = null;

            _View.Setup(v => v.ShowValidationResults(It.IsAny <ValidationResults>())).Callback((ValidationResults results) => {
                validationResults = results;
            });

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

            Assert.IsNotNull(validationResults);
            Assert.AreEqual(worksheet.Int("CountErrors"), validationResults.Results.Count());
            if (validationResults.Results.Count() > 0)
            {
                Assert.IsTrue(validationResults.Results.Where(r => r.Field == worksheet.ParseEnum <ValidationField>("Field") &&
                                                              r.Message == worksheet.String("Message") &&
                                                              r.IsWarning == worksheet.Bool("IsWarning")).Any());
            }
        }
Exemple #11
0
        public void WebSite_Image_Correct_Image_Is_Rendered()
        {
            ExcelWorksheetData worksheet   = new ExcelWorksheetData(TestContext);
            string             pathAndFile = worksheet.String("UrlPath");

            _WebSite.AttachSiteToServer(_WebServer.Object);

            var args = RequestReceivedEventArgsHelper.Create(_Request, _Response, pathAndFile, false);

            _WebServer.Raise(m => m.RequestReceived += null, args);
            Assert.AreEqual(true, args.Handled);

            byte[] content     = _OutputStream.ToArray();
            var    md5Checksum = new StringBuilder();

            using (var md5 = MD5.Create()) {
                foreach (var b in md5.ComputeHash(content))
                {
                    md5Checksum.AppendFormat("{0:X2}", b);
                }
            }

            Assert.AreEqual(worksheet.String("MimeType"), _Response.Object.MimeType);
            Assert.AreEqual(worksheet.Int("Length"), content.Length);
            Assert.AreEqual(worksheet.String("MD5"), md5Checksum.ToString(), true);
        }
        public void JsonSerialiser_WriteObject_Writes_Lists_Of_ValueTypes_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var container = new ValueListContainer();

            if (worksheet.EString("Value1") != null)
            {
                var list = new List <int>();
                for (int column = 1; column <= 3; ++column)
                {
                    var name = String.Format("Value{0}", column);
                    if (String.IsNullOrEmpty(worksheet.EString(name)))
                    {
                        continue;
                    }
                    list.Add(worksheet.Int(name));
                }

                container.List = list;
            }

            _JsonSerialiser.Initialise(typeof(ValueListContainer));
            _JsonSerialiser.WriteObject(_Stream, container);

            Assert.AreEqual(worksheet.EString("Json"), GetJson());
        }
Exemple #13
0
        public void Cidr_Parse_Parses_Addresses_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            // Uncomment this block if you want to restrict the test to just those rows with a RunThis of true
            // var runThis = worksheet.NBool("RunThis").GetValueOrDefault();
            // if(!runThis) Assert.Fail();

            var       address   = worksheet.EString("Parse");
            Exception exception = null;
            Cidr      cidr      = null;

            try {
                cidr = Cidr.Parse(address);
            } catch (Exception ex) {
                exception = ex;
            }

            Assert.AreEqual(exception != null, worksheet.NBool("Exception").GetValueOrDefault(), exception == null ? "Did not see exception" : exception.Message);
            if (exception == null)
            {
                Assert.AreEqual(GetExcelIPAddress(worksheet, "Address"), cidr.Address);
                Assert.AreEqual(GetExcelIPAddress(worksheet, "MaskedAddress"), cidr.MaskedAddress);
                Assert.AreEqual(worksheet.Int("BitmaskBits"), cidr.BitmaskBits);
                Assert.AreEqual(worksheet.UInt("IPv4Bitmask"), cidr.IPv4Bitmask);
                Assert.AreEqual(GetExcelIPAddress(worksheet, "From"), cidr.FirstMatchingAddress);
                Assert.AreEqual(GetExcelIPAddress(worksheet, "To"), cidr.LastMatchingAddress);
            }
        }
        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());
        }
Exemple #15
0
        public void Aircraft_UpdateCoordinates_Resets_Coordinates_If_Aircraft_Looks_To_Be_Moving_Impossibly_Quickly()
        {
            // Some aircraft's transponders report the wrong position. Further, some radios misinterpret position updates at
            // extreme ranges. We can guess the position is wrong if the position and timing of two updates would require the
            // aircraft to be moving at incredibly high speeds. When this is detected we should reset the trails, otherwise the
            // user sees long lines drawn across the map, or a scribble effect if the transponder is just reporting nonsense.

            var worksheet = new ExcelWorksheetData(TestContext);

            var time         = DateTime.UtcNow;
            var shortSeconds = 24 * 60 * 60; // seconds in a day

            _Aircraft.DataVersion = time.Ticks;
            _Aircraft.Latitude    = worksheet.Float("Lat1");
            _Aircraft.Longitude   = worksheet.Float("Lng1");
            _Aircraft.Track       = 1;
            _Aircraft.UpdateCoordinates(time, shortSeconds);

            int milliseconds = worksheet.Int("Milliseconds");

            time = time.AddMilliseconds(milliseconds);
            _Aircraft.DataVersion = time.Ticks;
            _Aircraft.Latitude    = worksheet.Float("Lat2");
            _Aircraft.Longitude   = worksheet.Float("Lng2");
            _Aircraft.Track       = 2;
            _Aircraft.UpdateCoordinates(time, shortSeconds);

            if (!worksheet.Bool("ResetTrail"))
            {
                if (milliseconds >= 1000)
                {
                    Assert.AreEqual(2, _Aircraft.FullCoordinates.Count);
                    Assert.AreEqual(2, _Aircraft.ShortCoordinates.Count);
                }
                else
                {
                    Assert.AreEqual(1, _Aircraft.FullCoordinates.Count);
                    Assert.AreEqual(1, _Aircraft.ShortCoordinates.Count);
                    Assert.AreEqual(1, _Aircraft.FullCoordinates[0].Heading);
                    Assert.AreEqual(1, _Aircraft.ShortCoordinates[0].Heading);
                }
            }
            else
            {
                if (milliseconds < 1000)
                {
                    Assert.AreEqual(0, _Aircraft.FullCoordinates.Count);
                    Assert.AreEqual(0, _Aircraft.ShortCoordinates.Count);
                }
                else
                {
                    Assert.AreEqual(1, _Aircraft.FullCoordinates.Count);
                    Assert.AreEqual(1, _Aircraft.ShortCoordinates.Count);
                    Assert.AreEqual(2, _Aircraft.FullCoordinates[0].Heading);
                    Assert.AreEqual(2, _Aircraft.ShortCoordinates[0].Heading);
                }
            }
        }
        public void WebSite_Image_Renders_Pictures_At_Correct_Size()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            CreateMonochromeImage("ImageRenderSize.png", worksheet.Int("OriginalWidth"), worksheet.Int("OriginalHeight"), Brushes.Red);
            ConfigurePictureManagerForPathAndFile(TestContext.TestDeploymentDir, "ImageRenderSize.png");

            _Configuration.BaseStationSettings.PicturesFolder = TestContext.TestDeploymentDir;
            _WebSite.AttachSiteToServer(_WebServer.Object);

            string pathAndFile = String.Format("/Images/Size-{0}/File-ImageRenderSize/Picture.png", worksheet.String("Size"));

            _WebServer.Raise(m => m.RequestReceived += null, RequestReceivedEventArgsHelper.Create(_Request, _Response, pathAndFile, false));

            using (var siteImage = (Bitmap)Bitmap.FromStream(_OutputStream)) {
                AssertImageIsMonochrome(siteImage, _Red, worksheet.Int("NewWidth"), worksheet.Int("NewHeight"));
            }
        }
Exemple #17
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);
                }
            }
        }
        public void JsonSerialiser_WriteObject_Honours_Important_DataMember_Attributes()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var obj = new Attributes()
            {
                OriginalName          = worksheet.Int("OriginalName"),
                NoEmitDefaultString   = worksheet.EString("NoEmitDefaultString"),
                NoEmitDefaultInt      = worksheet.Int("NoEmitDefaultInt"),
                NoEmitDefaultBool     = worksheet.Bool("NoEmitDefaultBool"),
                NoEmitDefaultLong     = worksheet.Long("NoEmitDefaultLong"),
                NoEmitDefaultDateTime = worksheet.DateTime("NoEmitDefaultDateTime"),
                NoEmitDefaultNullable = worksheet.NBool("NoEmitDefaultNullable"),
            };

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

            Assert.AreEqual(worksheet.EString("Json"), GetJson());
        }
Exemple #19
0
        public void ImageServer_Renders_Pictures_At_Correct_Size()
        {
            var worksheet      = new ExcelWorksheetData(TestContext);
            var originalWidth  = worksheet.Int("OriginalWidth");
            var originalHeight = worksheet.Int("OriginalHeight");
            var newWidth       = worksheet.Int("NewWidth");
            var newHeight      = worksheet.Int("NewHeight");
            var size           = worksheet.String("Size");

            CreateMonochromeImage("ImageRenderSize.png", originalWidth, originalHeight, Brushes.Red);
            ConfigurePictureManagerForFile(@"c:\web\ImageRenderSize.png", originalWidth, originalHeight, "ICAO", "REG");

            _Environment.RequestPath = $"/Images/Size-{size}/File-REG ICAO/Picture.png";
            _Pipeline.CallMiddleware(_Server.HandleRequest, _Environment.Environment);

            using (var stream = new MemoryStream(_Environment.ResponseBodyBytes)) {
                using (var siteImage = (Bitmap)Bitmap.FromStream(stream)) {
                    AssertImageIsMonochrome(siteImage, _Red, newWidth, newHeight);
                }
            }
        }
Exemple #20
0
        public void UniversalPlugAndPlayManager_PutServerOntoInternet_Adds_Correct_Mapping_To_Router()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Configuration.WebServerSettings.EnableUPnp = worksheet.Bool("CnfEnabled");
            _Configuration.WebServerSettings.UPnpPort   = worksheet.Int("CnfUPnpPort");
            _WebServer.Setup(s => s.NetworkIPAddress).Returns(worksheet.String("SvrAddress"));
            _WebServer.Setup(s => s.Port).Returns(worksheet.Int("SvrPort"));

            _Manager.Initialise();

            if (worksheet.String("RtrDescription") != null)
            {
                AddPortMapping(worksheet.String("RtrDescription"),
                               worksheet.Int("RtrExtPort"),
                               worksheet.String("RtrIntClient"),
                               worksheet.Int("RtrIntPort"),
                               worksheet.String("RtrProtocol"));
            }

            _Manager.StateChanged += _StateChangedEvent.Handler;
            _Manager.PutServerOntoInternet();

            _Provider.Verify(p => p.AddMapping(worksheet.Int("CnfUPnpPort"), "TCP", worksheet.Int("SvrPort"), worksheet.String("SvrAddress"), true, _Description),
                             worksheet.Bool("ExpectAdd") ? Times.Once() : Times.Never());

            Assert.AreEqual(worksheet.Bool("ExpectIsPresent"), _Manager.PortForwardingPresent);
            Assert.AreEqual(worksheet.Bool("ExpectStateChanged") ? 1 : 0, _StateChangedEvent.CallCount);
            if (_StateChangedEvent.CallCount > 0)
            {
                Assert.AreSame(_Manager, _StateChangedEvent.Sender);
                Assert.IsNotNull(_StateChangedEvent.Args);
            }
        }
Exemple #21
0
        public void UniversalPlugAndPlayManager_TakeServerOffInternet_Removes_Mapping_From_Router()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Configuration.WebServerSettings.EnableUPnp = worksheet.Bool("CnfEnabled");
            _Configuration.WebServerSettings.UPnpPort   = worksheet.Int("CnfUPnpPort");
            _Configuration.WebServerSettings.IsOnlyInternetServerOnLan = worksheet.Bool("CnfOnlyVRSOnNetwork");
            _WebServer.Setup(s => s.NetworkIPAddress).Returns(worksheet.String("SvrAddress"));
            _WebServer.Setup(s => s.Port).Returns(worksheet.Int("SvrPort"));

            _Manager.Initialise();
            if (worksheet.String("RtrDescription") != null)
            {
                AddPortMapping(worksheet.String("RtrDescription"),
                               worksheet.Int("RtrExtPort"),
                               worksheet.String("RtrIntClient"),
                               worksheet.Int("RtrIntPort"),
                               worksheet.String("RtrProtocol"));
                if (_PortMappings[0].Description == _Description && _PortMappings[0].ExternalPort == _Configuration.WebServerSettings.UPnpPort &&
                    _PortMappings[0].InternalClient == _WebServer.Object.NetworkIPAddress && _PortMappings[0].InternalPort == _WebServer.Object.Port &&
                    _PortMappings[0].Protocol == "TCP")
                {
                    _Manager.PutServerOntoInternet();
                }
            }

            _Manager.StateChanged += _StateChangedEvent.Handler;
            _Manager.TakeServerOffInternet();

            _Provider.Verify(p => p.RemoveMapping(worksheet.Int("CnfUPnpPort"), "TCP"),
                             worksheet.Bool("ExpectRemove") ? Times.Once() : Times.Never());

            Assert.AreEqual(worksheet.Bool("ExpectIsPresent"), _Manager.PortForwardingPresent);
            Assert.AreEqual(worksheet.Bool("ExpectStateChanged") ? 1 : 0, _StateChangedEvent.CallCount);
            if (_StateChangedEvent.CallCount > 0)
            {
                Assert.AreSame(_Manager, _StateChangedEvent.Sender);
                Assert.IsNotNull(_StateChangedEvent.Args);
            }
        }
        public void Describe_Airport_Formats_Airport_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var comparer = new IPAddressComparer();
            var lhs = worksheet.String("LHS") == null ? null : IPAddress.Parse(worksheet.String("LHS"));
            var rhs = worksheet.String("RHS") == null ? null : IPAddress.Parse(worksheet.String("RHS"));
            var expectedResult = worksheet.Int("Result");

            var result = comparer.Compare(lhs, rhs);
            if(expectedResult < 0)      Assert.IsTrue(result < 0);
            else if(expectedResult > 0) Assert.IsTrue(result > 0);
            else                        Assert.AreEqual(0, result);
        }
Exemple #23
0
        public void UniversalPlugAndPlayManager_Trash_Mappings_Removed_During_Initialise()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            if (worksheet.String("RtrDescription") != null)
            {
                AddPortMapping(worksheet.String("RtrDescription"),
                               worksheet.Int("RtrExtPort"),
                               worksheet.String("RtrIntClient"),
                               worksheet.Int("RtrIntPort"),
                               worksheet.String("RtrProtocol"));
            }

            _Configuration.WebServerSettings.EnableUPnp = worksheet.Bool("CnfEnabled");
            _Configuration.WebServerSettings.UPnpPort   = worksheet.Int("CnfUPnpPort");
            _Configuration.WebServerSettings.IsOnlyInternetServerOnLan = worksheet.Bool("CnfOnlyVRSOnNetwork");
            _WebServer.Setup(s => s.NetworkIPAddress).Returns(worksheet.String("SvrAddress"));
            _WebServer.Setup(s => s.Port).Returns(worksheet.Int("SvrPort"));

            _Manager.Initialise();

            _Provider.Verify(p => p.RemoveMapping(worksheet.Int("RtrExtPort"), worksheet.String("RtrProtocol")),
                             worksheet.Bool("ExpectRemove") ? Times.Once() : Times.Never());
        }
Exemple #24
0
        public void Cidr_TryParse_Parses_Addresses_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            Cidr cidr;
            var  address = worksheet.EString("Parse");
            var  parsed  = Cidr.TryParse(address, out cidr);

            Assert.AreEqual(!parsed, worksheet.NBool("Exception").GetValueOrDefault());
            if (parsed)
            {
                Assert.AreEqual(GetExcelIPAddress(worksheet, "Address"), cidr.Address);
                Assert.AreEqual(GetExcelIPAddress(worksheet, "MaskedAddress"), cidr.MaskedAddress);
                Assert.AreEqual(worksheet.Int("BitmaskBits"), cidr.BitmaskBits);
                Assert.AreEqual(worksheet.UInt("IPv4Bitmask"), cidr.IPv4Bitmask);
            }
        }
Exemple #25
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 PluginSettingsStorage_Load_Returns_Parsed_File_Content_If_File_Is_Present()
        {
            var worksheet = new ExcelWorksheetData(TestContext);
            var lines     = new List <string>();

            foreach (var line in worksheet.EString("Lines").Split('\n'))
            {
                lines.Add(line);
            }
            _Provider.Setup(p => p.FileReadAllLines(It.Is <string>(n => n.Equals(_ExpectedFileName, StringComparison.OrdinalIgnoreCase)))).Returns(lines.ToArray());

            var settings = _Storage.Load();

            Assert.AreEqual(worksheet.Int("Count"), settings.Values.Count);
            for (int i = 1; i <= settings.Values.Count; ++i)
            {
                Assert.AreEqual(worksheet.EString(String.Format("Key{0}", i)), settings.Values.Keys[i - 1]);
                Assert.AreEqual(worksheet.EString(String.Format("Value{0}", i)), settings.Values[i - 1]);
            }
        }
Exemple #27
0
        public void ImageServer_Can_Create_Blank_Images_Dynamically()
        {
            ExcelWorksheetData worksheet = new ExcelWorksheetData(TestContext);

            _Environment.RequestPath = worksheet.String("PathAndFile");
            _Pipeline.CallMiddleware(_Server.HandleRequest, _Environment.Environment);

            if (worksheet.String("Width") == null)
            {
                Assert.AreEqual(0, _Environment.ResponseBodyBytes.Length);
                Assert.IsTrue(_Pipeline.NextMiddlewareCalled);
            }
            else
            {
                Assert.IsFalse(_Pipeline.NextMiddlewareCalled);
                using (var stream = new MemoryStream(_Environment.ResponseBodyBytes)) {
                    using (var image = (Bitmap)Bitmap.FromStream(stream)) {
                        AssertImageIsMonochrome(image, _Transparent, worksheet.Int("Width"), worksheet.Int("Height"));
                    }
                }
            }
        }
Exemple #28
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);
        }
        public void WebSite_Image_Can_Create_Blank_Images_Dynamically()
        {
            ExcelWorksheetData worksheet = new ExcelWorksheetData(TestContext);

            _WebSite.AttachSiteToServer(_WebServer.Object);

            var args = RequestReceivedEventArgsHelper.Create(_Request, _Response, worksheet.String("PathAndFile"), false);

            _WebServer.Raise(m => m.RequestReceived += null, args);

            if (worksheet.String("Width") == null)
            {
                Assert.AreEqual(false, args.Handled);
                Assert.AreEqual(0, _OutputStream.Length);
                Assert.AreEqual(0, _Response.Object.ContentLength);
            }
            else
            {
                using (var siteImage = (Bitmap)Bitmap.FromStream(_OutputStream)) {
                    AssertImageIsMonochrome(siteImage, _Transparent, worksheet.Int("Width"), worksheet.Int("Height"));
                }
            }
        }
        public void Describe_Airport_Formats_Airport_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var comparer       = new IPAddressComparer();
            var lhs            = worksheet.String("LHS") == null ? null : IPAddress.Parse(worksheet.String("LHS"));
            var rhs            = worksheet.String("RHS") == null ? null : IPAddress.Parse(worksheet.String("RHS"));
            var expectedResult = worksheet.Int("Result");

            var result = comparer.Compare(lhs, rhs);

            if (expectedResult < 0)
            {
                Assert.IsTrue(result < 0);
            }
            else if (expectedResult > 0)
            {
                Assert.IsTrue(result > 0);
            }
            else
            {
                Assert.AreEqual(0, result);
            }
        }
        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);
        }
Exemple #32
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
        }
        private void Do_GetFlightsAllVersions_Can_Return_Subset_Of_Rows(bool getFlights)
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            int flightCount = worksheet.Int("Flights");

            var aircraft = CreateAircraft();
            AddAircraft(aircraft);

            for(int flightNumber = 0;flightNumber < flightCount;++flightNumber) {
                var flight = CreateFlight(aircraft, (flightNumber + 1).ToString());
                AddFlight(flight);
            }

            List<BaseStationFlight> flights;
            if(getFlights) flights = _Database.GetFlights(_Criteria, worksheet.Int("StartRow"), worksheet.Int("EndRow"), "CALLSIGN", true, null, false);
            else           flights = _Database.GetFlightsForAircraft(aircraft, _Criteria, worksheet.Int("StartRow"), worksheet.Int("EndRow"), "CALLSIGN", true, null, false);

            var rows = "";
            foreach(var flight in flights) {
                rows = String.Format("{0}{1}{2}", rows, rows.Length == 0 ? "" : ",", flight.Callsign);
            }

            Assert.AreEqual(worksheet.Int("ExpectedCount"), flights.Count);
            Assert.AreEqual(worksheet.EString("ExpectedRows"), rows);
        }
        public void PluginSettingsStorage_Save_Translates_Key_Values_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var settings = new PluginSettings();
            for(int i = 1;i <= worksheet.Int("Count");++i) {
                var key = worksheet.EString(String.Format("Key{0}", i));
                var value = worksheet.EString(String.Format("Value{0}", i));
                if(value != null) value = value.Replace(@"\n", "\n").Replace(@"\r", "\r");
                settings.Values.Add(key, value);
            }

            _Provider.Setup(p => p.FileWriteAllLines(It.IsAny<string>(), It.IsAny<string[]>())).Callback((string fileName, string[] lines) => {
                Assert.AreEqual(worksheet.Int("LineCount"), lines.Length);
                for(int i = 1;i <= worksheet.Int("LineCount");++i) {
                    Assert.AreEqual(worksheet.EString(String.Format("Line{0}", i)), lines[i - 1]);
                }
            });

            _Storage.Save(settings);
            _Provider.Verify(p => p.FileWriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()), Times.Once());
        }
        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_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 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 UniversalPlugAndPlayManager_TakeServerOffInternet_Removes_Mapping_From_Router()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Configuration.WebServerSettings.EnableUPnp = worksheet.Bool("CnfEnabled");
            _Configuration.WebServerSettings.UPnpPort = worksheet.Int("CnfUPnpPort");
            _Configuration.WebServerSettings.IsOnlyInternetServerOnLan = worksheet.Bool("CnfOnlyVRSOnNetwork");
            _WebServer.Setup(s => s.NetworkIPAddress).Returns(worksheet.String("SvrAddress"));
            _WebServer.Setup(s => s.Port).Returns(worksheet.Int("SvrPort"));

            _Manager.Initialise();
            if(worksheet.String("RtrDescription") != null) {
                AddPortMapping(worksheet.String("RtrDescription"),
                               worksheet.Int("RtrExtPort"),
                               worksheet.String("RtrIntClient"),
                               worksheet.Int("RtrIntPort"),
                               worksheet.String("RtrProtocol"));
                if(_PortMappings[0].Description == _Description && _PortMappings[0].ExternalPort == _Configuration.WebServerSettings.UPnpPort &&
                   _PortMappings[0].InternalClient == _WebServer.Object.NetworkIPAddress && _PortMappings[0].InternalPort == _WebServer.Object.Port &&
                   _PortMappings[0].Protocol == "TCP") _Manager.PutServerOntoInternet();
            }

            _Manager.StateChanged += _StateChangedEvent.Handler;
            _Manager.TakeServerOffInternet();

            _Provider.Verify(p => p.RemoveMapping(worksheet.Int("CnfUPnpPort"), "TCP"),
                worksheet.Bool("ExpectRemove") ? Times.Once() : Times.Never());

            Assert.AreEqual(worksheet.Bool("ExpectIsPresent"), _Manager.PortForwardingPresent);
            Assert.AreEqual(worksheet.Bool("ExpectStateChanged") ? 1 : 0, _StateChangedEvent.CallCount);
            if(_StateChangedEvent.CallCount > 0) {
                Assert.AreSame(_Manager, _StateChangedEvent.Sender);
                Assert.IsNotNull(_StateChangedEvent.Args);
            }
        }
        public void WebSite_Image_Renders_Pictures_At_Correct_Size()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Configuration.BaseStationSettings.PicturesFolder = TestContext.TestDeploymentDir;
            _WebSite.AttachSiteToServer(_WebServer.Object);

            CreateMonochromeImage("ImageRenderSize.png", worksheet.Int("OriginalWidth"), worksheet.Int("OriginalHeight"), Brushes.Red);
            _AircraftPictureManager.Setup(p => p.FindPicture(_DirectoryCache.Object, It.IsAny<string>(), It.IsAny<string>())).Returns(Path.Combine(TestContext.TestDeploymentDir, "ImageRenderSize.png"));

            string pathAndFile = String.Format("/Images/Size-{0}/File-ImageRenderSize/Picture.png", worksheet.String("Size"));
            _WebServer.Raise(m => m.RequestReceived += null, RequestReceivedEventArgsHelper.Create(_Request, _Response, pathAndFile, false));

            using(var siteImage = (Bitmap)Bitmap.FromStream(_OutputStream)) {
                AssertImageIsMonochrome(siteImage, _Red, worksheet.Int("NewWidth"), worksheet.Int("NewHeight"));
            }
        }
        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 WebSite_Image_Can_Create_Blank_Images_Dynamically()
        {
            ExcelWorksheetData worksheet = new ExcelWorksheetData(TestContext);
            _WebSite.AttachSiteToServer(_WebServer.Object);

            var args = RequestReceivedEventArgsHelper.Create(_Request, _Response, worksheet.String("PathAndFile"), false);
            _WebServer.Raise(m => m.RequestReceived += null, args);

            if(worksheet.String("Width") == null) {
                Assert.AreEqual(false, args.Handled);
                Assert.AreEqual(0, _OutputStream.Length);
                Assert.AreEqual(0, _Response.Object.ContentLength);
            } else {
                using(var siteImage = (Bitmap)Bitmap.FromStream(_OutputStream)) {
                    AssertImageIsMonochrome(siteImage, _Transparent, worksheet.Int("Width"), worksheet.Int("Height"));
                }
            }
        }
        public void WebSite_Image_Correct_Image_Is_Rendered()
        {
            ExcelWorksheetData worksheet = new ExcelWorksheetData(TestContext);
            string pathAndFile = worksheet.String("UrlPath");

            _WebSite.AttachSiteToServer(_WebServer.Object);

            var args = RequestReceivedEventArgsHelper.Create(_Request, _Response, pathAndFile, false);
            _WebServer.Raise(m => m.RequestReceived += null, args);
            Assert.AreEqual(true, args.Handled);

            byte[] content = _OutputStream.ToArray();
            var md5Checksum = new StringBuilder();
            using(var md5 = MD5.Create()) {
                foreach(var b in md5.ComputeHash(content)) {
                    md5Checksum.AppendFormat("{0:X2}", b);
                }
            }

            Assert.AreEqual(worksheet.String("MimeType"), _Response.Object.MimeType);
            Assert.AreEqual(worksheet.Int("Length"), content.Length);
            Assert.AreEqual(worksheet.String("MD5"), md5Checksum.ToString(), true);
        }
        public void BaseStationAircraftList_MessageReceived_Ignores_Messages_With_Invalid_Icao24()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _AircraftList.Start();

            _BaseStationMessage.Icao24 = worksheet.EString("Icao");
            _Port30003Listener.Raise(m => m.Port30003MessageReceived += null, _BaseStationMessageEventArgs);

            bool expectValid = worksheet.Bool("IsValid");
            if(!expectValid) {
                long snapshotTime, snapshotDataVersion;
                Assert.AreEqual(0, _AircraftList.TakeSnapshot(out snapshotTime, out snapshotDataVersion).Count);
            } else {
                Assert.IsNotNull(_AircraftList.FindAircraft(worksheet.Int("UniqueId")));
            }
        }
        /// <summary>
        /// Returns a mock flight record with values filled from a spreadsheet row, starting from the column number passed across.
        /// </summary>
        /// <param name="expected"></param>
        /// <param name="firstOrdinal"></param>
        /// <returns></returns>
        /// <remarks>
        /// The columns are read in the following order:
        /// AircraftID, Callsign, EndTime, FirstAltitude, FirstGroundSpeed, FirstIsOnGround, FirstLat, FirstLon, FirstSquawk, FirstTrack, FirstVerticalRate, HadAlert,
        /// HadEmergency, HadSpi, LastAltitude, LastGroundSpeed, LastIsOnGround, LastLat, LastLon, LastSquawk, LastTrack, LastVerticalRate, NumADSBMsgRec, NumModeSMsgRec,
        /// NumIDMsgRec, NumSurPosMsgRec, NumAirPosMsgRec, NumAirVelMsgRec, NumSurAltMsgRec, NumSurIDMsgRec, NumAirToAirMsgRec, NumAirCallRepMsgRec, NumPosMsgRec
        /// and StartTime
        /// </remarks>
        private BaseStationFlight LoadFlightFromSpreadsheet(ExcelWorksheetData worksheet, int firstOrdinal = 0, BaseStationFlight copyIntoFlight = null)
        {
            int ordinal = firstOrdinal;

            var aircraft = CreateAircraft();
            aircraft.AircraftID = worksheet.Int(ordinal++);

            var result = copyIntoFlight == null ? CreateFlight(aircraft) : copyIntoFlight;
            result.AircraftID = aircraft.AircraftID;
            result.Callsign = worksheet.EString(ordinal++);
            result.EndTime = worksheet.DateTime(ordinal++);
            result.FirstAltitude = worksheet.Int(ordinal++);
            result.FirstGroundSpeed = worksheet.Float(ordinal++);
            result.FirstIsOnGround = worksheet.Bool(ordinal++);
            result.FirstLat = worksheet.Float(ordinal++);
            result.FirstLon = worksheet.Float(ordinal++);
            result.FirstSquawk = worksheet.Int(ordinal++);
            result.FirstTrack = worksheet.Float(ordinal++);
            result.FirstVerticalRate = worksheet.Int(ordinal++);
            result.HadAlert = worksheet.Bool(ordinal++);
            result.HadEmergency = worksheet.Bool(ordinal++);
            result.HadSpi = worksheet.Bool(ordinal++);
            result.LastAltitude = worksheet.Int(ordinal++);
            result.LastGroundSpeed = worksheet.Float(ordinal++);
            result.LastIsOnGround = worksheet.Bool(ordinal++);
            result.LastLat = worksheet.Float(ordinal++);
            result.LastLon = worksheet.Float(ordinal++);
            result.LastSquawk = worksheet.Int(ordinal++);
            result.LastTrack = worksheet.Float(ordinal++);
            result.LastVerticalRate = worksheet.Int(ordinal++);
            result.NumADSBMsgRec = worksheet.Int(ordinal++);
            result.NumModeSMsgRec = worksheet.Int(ordinal++);
            result.NumIDMsgRec = worksheet.Int(ordinal++);
            result.NumSurPosMsgRec = worksheet.Int(ordinal++);
            result.NumAirPosMsgRec = worksheet.Int(ordinal++);
            result.NumAirVelMsgRec = worksheet.Int(ordinal++);
            result.NumSurAltMsgRec = worksheet.Int(ordinal++);
            result.NumSurIDMsgRec = worksheet.Int(ordinal++);
            result.NumAirToAirMsgRec = worksheet.Int(ordinal++);
            result.NumAirCallRepMsgRec = worksheet.Int(ordinal++);
            result.NumPosMsgRec = worksheet.Int(ordinal++);
            result.StartTime = worksheet.DateTime(ordinal++);

            return result;
        }
        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());
            }
        }
        public void UniversalPlugAndPlayManager_PutServerOntoInternet_Adds_Correct_Mapping_To_Router()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Configuration.WebServerSettings.EnableUPnp = worksheet.Bool("CnfEnabled");
            _Configuration.WebServerSettings.UPnpPort = worksheet.Int("CnfUPnpPort");
            _WebServer.Setup(s => s.NetworkIPAddress).Returns(worksheet.String("SvrAddress"));
            _WebServer.Setup(s => s.Port).Returns(worksheet.Int("SvrPort"));

            _Manager.Initialise();

            if(worksheet.String("RtrDescription") != null) {
                AddPortMapping(worksheet.String("RtrDescription"),
                               worksheet.Int("RtrExtPort"),
                               worksheet.String("RtrIntClient"),
                               worksheet.Int("RtrIntPort"),
                               worksheet.String("RtrProtocol"));
            }

            _Manager.StateChanged += _StateChangedEvent.Handler;
            _Manager.PutServerOntoInternet();

            _Provider.Verify(p => p.AddMapping(worksheet.Int("CnfUPnpPort"), "TCP", worksheet.Int("SvrPort"), worksheet.String("SvrAddress"), true, _Description),
                worksheet.Bool("ExpectAdd") ? Times.Once() : Times.Never());

            Assert.AreEqual(worksheet.Bool("ExpectIsPresent"), _Manager.PortForwardingPresent);
            Assert.AreEqual(worksheet.Bool("ExpectStateChanged") ? 1 : 0, _StateChangedEvent.CallCount);
            if(_StateChangedEvent.CallCount > 0) {
                Assert.AreSame(_Manager, _StateChangedEvent.Sender);
                Assert.IsNotNull(_StateChangedEvent.Args);
            }
        }
        public void MergedFeedListener_SetListener_Events_Are_Filtered_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Component1.Setup(r => r.IsMlatFeed).Returns(worksheet.Bool("L1MLAT"));
            _Component2.Setup(r => r.IsMlatFeed).Returns(worksheet.Bool("L2MLAT"));

            _MergedFeed.SetListeners(_Components);
            _MergedFeed.IcaoTimeout = worksheet.Int("IcaoTimeout");
            _MergedFeed.IgnoreAircraftWithNoPosition = worksheet.Bool("IgnoreNoPos");
            var startTime = new DateTime(2013, 10, 8, 14, 56, 21, 0);

            for (var i = 1; i <= 3; ++i)
            {
                var listenerNumberName = String.Format("Listener{0}", i);
                var icaoName           = String.Format("ICAO{0}", i);
                var msOffsetName       = String.Format("MSOffset{0}", i);
                var hasPosnName        = String.Format("HasPosn{0}", i);
                var hasHeadName        = String.Format("HasHead{0}", i);
                var hasSpeedName       = String.Format("HasSpeed{0}", i);
                var isMlatName         = String.Format("IsMlat{0}", i);
                var passesName         = String.Format("Passes{0}", i);
                var isOutOfBandName    = String.Format("OOB{0}", i);

                if (worksheet.String(listenerNumberName) != null)
                {
                    var listenerNumber  = worksheet.Int(listenerNumberName);
                    var icao            = worksheet.String(icaoName);
                    var msOffset        = worksheet.Int(msOffsetName);
                    var hasZeroPosn     = worksheet.String(hasPosnName) == "0";
                    var hasPosn         = hasZeroPosn ? true : worksheet.Bool(hasPosnName);
                    var hasHead         = worksheet.Bool(hasHeadName);
                    var hasSpeed        = worksheet.Bool(hasSpeedName);
                    var isMlat          = worksheet.Bool(isMlatName);
                    var resetExpected   = worksheet.String(passesName) == "True";
                    var messageExpected = resetExpected || worksheet.String(passesName) == "NoReset";
                    var isOutOfBand     = worksheet.Bool(isOutOfBandName);

                    Mock <IListener> listener;
                    switch (listenerNumber)
                    {
                    case 1:     listener = _Listener1; break;

                    case 2:     listener = _Listener2; break;

                    default:    throw new NotImplementedException();
                    }

                    _Clock.UtcNowValue = startTime.AddMilliseconds(msOffset);

                    var baseStationMessageEventArgs = new BaseStationMessageEventArgs(new BaseStationMessage()
                    {
                        Icao24 = icao
                    });
                    if (hasZeroPosn)
                    {
                        baseStationMessageEventArgs.Message.Latitude = baseStationMessageEventArgs.Message.Longitude = 0.0;
                    }
                    else if (hasPosn)
                    {
                        baseStationMessageEventArgs.Message.Latitude = baseStationMessageEventArgs.Message.Longitude = 1.0;
                    }
                    if (hasHead)
                    {
                        baseStationMessageEventArgs.Message.Track = 2;
                    }
                    if (hasSpeed)
                    {
                        baseStationMessageEventArgs.Message.GroundSpeed = 3;
                    }
                    if (isMlat)
                    {
                        baseStationMessageEventArgs.Message.IsMlat = true;
                    }

                    var baseStationMessageEventRecorder = new EventRecorder <BaseStationMessageEventArgs>();
                    _MergedFeed.Port30003MessageReceived += baseStationMessageEventRecorder.Handler;

                    var positionResetEventArgs     = new EventArgs <string>(icao);
                    var positionResetEventRecorder = new EventRecorder <EventArgs <string> >();
                    _MergedFeed.PositionReset += positionResetEventRecorder.Handler;

                    listener.Raise(r => r.Port30003MessageReceived += null, baseStationMessageEventArgs);
                    listener.Raise(r => r.PositionReset            += null, positionResetEventArgs);

                    var failDetails = String.Format("Failed on message {0} {{0}}", i);
                    if (!messageExpected)
                    {
                        Assert.AreEqual(0, baseStationMessageEventRecorder.CallCount, failDetails, "BaseStationMessage");
                        Assert.AreEqual(0, positionResetEventRecorder.CallCount, failDetails, "PostionReset");
                    }
                    else
                    {
                        Assert.AreEqual(1, baseStationMessageEventRecorder.CallCount, failDetails, "BaseStationMessage");
                        Assert.AreSame(_MergedFeed, baseStationMessageEventRecorder.Sender);

                        Assert.AreSame(baseStationMessageEventArgs.Message, baseStationMessageEventRecorder.Args.Message);
                        Assert.AreEqual(isOutOfBand, baseStationMessageEventRecorder.Args.IsOutOfBand);

                        if (!resetExpected)
                        {
                            Assert.AreEqual(0, positionResetEventRecorder.CallCount, failDetails, "PostionReset");
                        }
                        else
                        {
                            Assert.AreEqual(1, positionResetEventRecorder.CallCount, failDetails, "PositionReset");
                            Assert.AreSame(_MergedFeed, positionResetEventRecorder.Sender);
                            Assert.AreSame(positionResetEventArgs, positionResetEventRecorder.Args);
                        }
                    }
                }
            }
        }
        public void UniversalPlugAndPlayManager_Trash_Mappings_Removed_During_Initialise()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            if(worksheet.String("RtrDescription") != null) {
                AddPortMapping(worksheet.String("RtrDescription"),
                               worksheet.Int("RtrExtPort"),
                               worksheet.String("RtrIntClient"),
                               worksheet.Int("RtrIntPort"),
                               worksheet.String("RtrProtocol"));
            }

            _Configuration.WebServerSettings.EnableUPnp = worksheet.Bool("CnfEnabled");
            _Configuration.WebServerSettings.UPnpPort = worksheet.Int("CnfUPnpPort");
            _Configuration.WebServerSettings.IsOnlyInternetServerOnLan = worksheet.Bool("CnfOnlyVRSOnNetwork");
            _WebServer.Setup(s => s.NetworkIPAddress).Returns(worksheet.String("SvrAddress"));
            _WebServer.Setup(s => s.Port).Returns(worksheet.Int("SvrPort"));

            _Manager.Initialise();

            _Provider.Verify(p => p.RemoveMapping(worksheet.Int("RtrExtPort"), worksheet.String("RtrProtocol")),
                worksheet.Bool("ExpectRemove") ? Times.Once() : Times.Never());
        }
        public void JsonSerialiser_WriteObject_Honours_Important_DataMember_Attributes()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            var obj = new Attributes() {
                OriginalName = worksheet.Int("OriginalName"),
                NoEmitDefaultString = worksheet.EString("NoEmitDefaultString"),
                NoEmitDefaultInt = worksheet.Int("NoEmitDefaultInt"),
                NoEmitDefaultBool = worksheet.Bool("NoEmitDefaultBool"),
                NoEmitDefaultLong = worksheet.Long("NoEmitDefaultLong"),
                NoEmitDefaultDateTime = worksheet.DateTime("NoEmitDefaultDateTime"),
                NoEmitDefaultNullable = worksheet.NBool("NoEmitDefaultNullable"),
            };

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

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

            _Translator.AcceptIcaoInPI0Count = worksheet.Int("PI0Count");
            _Translator.AcceptIcaoInPI0Milliseconds = worksheet.Int("PI0Ms");
            _Translator.AcceptIcaoInNonPICount = worksheet.Int("NonPICount");
            _Translator.AcceptIcaoInNonPIMilliseconds = worksheet.Int("NonPIMs");

            IEnumerable<ModeSMessage> messages;
            switch(worksheet.String("DownlinkFormat").ToUpper()) {
                case "HASPI":       messages = CreateModeSMessagesWithPIField(); break;
                case "NOPI":        messages = CreateModeSMessagesWithNoPIField(); break;
                default:            throw new NotImplementedException();
            }

            foreach(var message in messages) {
                message.Icao24 = CreateRandomIcao24();
                var originalDF = message.DownlinkFormat;
                var originalParity = message.ParityInterrogatorIdentifier;

                for(var messageNumber = 1;messageNumber <= 3;++messageNumber) {
                    var timeColumn = String.Format("Msg{0}Time", messageNumber);
                    var acceptedColumn = String.Format("Accepted{0}", messageNumber);
                    var piColumn = String.Format("Msg{0}PI", messageNumber);

                    if(worksheet.String(acceptedColumn) != null) {
                        message.DownlinkFormat = originalDF;
                        message.ParityInterrogatorIdentifier = worksheet.NInt(piColumn);
                        if(message.ParityInterrogatorIdentifier == null && originalParity != null)      message.DownlinkFormat = DownlinkFormat.ShortAirToAirSurveillance;
                        else if(message.ParityInterrogatorIdentifier != null && originalParity == null) message.DownlinkFormat = DownlinkFormat.ExtendedSquitter;

                        var now = _NowUtc.AddMilliseconds(worksheet.Int(timeColumn));
                        _Provider.Setup(r => r.UtcNow).Returns(now);
                        var accepted = _Translator.Translate(now, message, null) != null;
                        var expected = worksheet.Bool(acceptedColumn);

                        Assert.AreEqual(expected, accepted, "{0} message {1}: {2}", originalDF, messageNumber, worksheet.String("Comments"));
                    }
                }
            }
        }
        public void AdsbTranslator_Translate_Decodes_Messages_Correctly()
        {
            var worksheet = new ExcelWorksheetData(TestContext);
            var expectedValue = new SpreadsheetFieldValue(worksheet, 17);

            var bits = worksheet.String("ExtendedSquitterMessage");
            var bytes = TestUtilities.ConvertBitStringToBytes(bits);
            var df = worksheet.String("DF");

            int countTestsPerformed = 0;
            for(var modeSDownlinkFormats = 0;modeSDownlinkFormats < 5;++modeSDownlinkFormats) {
                DownlinkFormat downlinkFormat = DownlinkFormat.ShortAirToAirSurveillance;
                ControlField? controlField = null;
                ApplicationField? applicationField = null;
                switch(modeSDownlinkFormats) {
                    case 0: downlinkFormat = DownlinkFormat.ExtendedSquitter; break;
                    case 1: downlinkFormat = DownlinkFormat.ExtendedSquitterNonTransponder; controlField = ControlField.AdsbDeviceTransmittingIcao24; break;
                    case 2: downlinkFormat = DownlinkFormat.ExtendedSquitterNonTransponder; controlField = ControlField.AdsbDeviceNotTransmittingIcao24; break;
                    case 3: downlinkFormat = DownlinkFormat.ExtendedSquitterNonTransponder; controlField = ControlField.AdsbRebroadcastOfExtendedSquitter; break;
                    case 4: downlinkFormat = DownlinkFormat.MilitaryExtendedSquitter; applicationField = ApplicationField.ADSB; break;
                }
                if(df != "ALL") {
                    if((int)downlinkFormat != worksheet.Int("DF")) continue;
                    if((int?)controlField != worksheet.NInt("CF")) continue;
                    if((int?)applicationField != worksheet.NInt("AF")) continue;
                }
                ++countTestsPerformed;

                TestCleanup();
                TestInitialise();

                _ModeSMessage.DownlinkFormat = downlinkFormat;
                _ModeSMessage.ControlField = controlField;
                _ModeSMessage.ApplicationField = applicationField;
                _ModeSMessage.ExtendedSquitterMessage = bytes.ToArray();

                var message = _Translator.Translate(_ModeSMessage);
                var failMessage = String.Format("Failed for DF:{0} CF:{1} AF:{2}", (int)_ModeSMessage.DownlinkFormat, (int?)_ModeSMessage.ControlField, (int?)_ModeSMessage.ApplicationField);

                var countMessageObjects = 0;
                object subMessage = null;
                if(message.AirbornePosition != null)            { ++countMessageObjects; subMessage = message.AirbornePosition; }
                if(message.SurfacePosition != null)             { ++countMessageObjects; subMessage = message.SurfacePosition; }
                if(message.IdentifierAndCategory != null)       { ++countMessageObjects; subMessage = message.IdentifierAndCategory; }
                if(message.AirborneVelocity != null)            { ++countMessageObjects; subMessage = message.AirborneVelocity; }
                if(message.AircraftStatus != null)              { ++countMessageObjects; subMessage = message.AircraftStatus; }
                if(message.TargetStateAndStatus != null)        { ++countMessageObjects; subMessage = message.TargetStateAndStatus; }
                if(message.AircraftOperationalStatus != null)   { ++countMessageObjects; subMessage = message.AircraftOperationalStatus; }
                Assert.AreEqual(1, countMessageObjects, failMessage);

                // Extract values that can appear on more than one message type
                CompactPositionReportingCoordinate cpr = null;
                bool? posTime = null;
                EmergencyState? emergencyState = null;
                byte? nacP = null;
                bool? nicBaro = null;
                byte? sil = null;
                bool? silSupplement = null;
                bool? isRebroadcast = null;
                if(message.AirbornePosition != null) {
                    cpr = message.AirbornePosition.CompactPosition;
                    posTime = message.AirbornePosition.PositionTimeIsExact;
                } else if(message.SurfacePosition != null) {
                    cpr = message.SurfacePosition.CompactPosition;
                    posTime = message.SurfacePosition.PositionTimeIsExact;
                } else if(message.AircraftStatus != null && message.AircraftStatus.EmergencyStatus != null) {
                    emergencyState = message.AircraftStatus.EmergencyStatus.EmergencyState;
                } else if(message.TargetStateAndStatus != null && message.TargetStateAndStatus.Version1 != null) {
                    nacP = message.TargetStateAndStatus.Version1.NacP;
                    nicBaro = message.TargetStateAndStatus.Version1.NicBaro;
                    sil = message.TargetStateAndStatus.Version1.Sil;
                    emergencyState = message.TargetStateAndStatus.Version1.EmergencyState;
                } else if(message.TargetStateAndStatus != null && message.TargetStateAndStatus.Version2 != null) {
                    nacP = message.TargetStateAndStatus.Version2.NacP;
                    nicBaro = message.TargetStateAndStatus.Version2.NicBaro;
                    sil = message.TargetStateAndStatus.Version2.Sil;
                    silSupplement = message.TargetStateAndStatus.Version2.SilSupplement;
                    isRebroadcast = message.TargetStateAndStatus.Version2.IsRebroadcast;
                } else if(message.AircraftOperationalStatus != null) {
                    nacP = message.AircraftOperationalStatus.NacP;
                    nicBaro = message.AircraftOperationalStatus.NicBaro;
                    sil = message.AircraftOperationalStatus.Sil;
                    silSupplement = message.AircraftOperationalStatus.SilSupplement;
                    isRebroadcast = message.AircraftOperationalStatus.IsRebroadcast;
                }

                // Extract the full list of properties to check
                var checkProperties = message.GetType().GetProperties().AsQueryable();
                checkProperties = checkProperties.Concat(subMessage.GetType().GetProperties());
                if(message.AircraftStatus != null) {
                    switch(message.AircraftStatus.AircraftStatusType) {
                        case AircraftStatusType.EmergencyStatus:
                            checkProperties = checkProperties.Concat(message.AircraftStatus.EmergencyStatus.GetType().GetProperties());
                            break;
                        case AircraftStatusType.TcasResolutionAdvisoryBroadcast:
                            checkProperties = checkProperties.Concat(message.AircraftStatus.TcasResolutionAdvisory.GetType().GetProperties());
                            break;
                    }
                }
                if(message.TargetStateAndStatus != null) {
                    switch(message.TargetStateAndStatus.TargetStateAndStatusType) {
                        case TargetStateAndStatusType.Version1: checkProperties = checkProperties.Concat(message.TargetStateAndStatus.Version1.GetType().GetProperties()); break;
                        case TargetStateAndStatusType.Version2: checkProperties = checkProperties.Concat(message.TargetStateAndStatus.Version2.GetType().GetProperties()); break;
                    }
                }

                Assert.IsNotNull(message, failMessage);
                foreach(var messageProperty in checkProperties) {
                    switch(messageProperty.Name) {
                        case "AdsbVersion":                         Assert.AreEqual(expectedValue.GetNByte("V"), message.AircraftOperationalStatus.AdsbVersion, failMessage); break;
                        case "AirborneCapability":                  Assert.AreEqual(expectedValue.GetNInt("AC", true), (int?)message.AircraftOperationalStatus.AirborneCapability, failMessage); break;
                        case "AirbornePosition":                    break;
                        case "AirborneVelocity":                    break;
                        case "AircraftOperationalStatus":           break;
                        case "AircraftOperationalStatusType":       Assert.AreEqual(expectedValue.GetEnum<AircraftOperationalStatusType>("AST"), message.AircraftOperationalStatus.AircraftOperationalStatusType, failMessage); break;
                        case "AircraftStatus":                      break;
                        case "AircraftStatusType":                  Assert.AreEqual(expectedValue.GetEnum<AircraftStatusType>("AST"), message.AircraftStatus.AircraftStatusType, failMessage); break;
                        case "Airspeed":                            Assert.AreEqual(expectedValue.GetNDouble("AS"), message.AirborneVelocity.Airspeed, failMessage); break;
                        case "AirspeedExceeded":                    Assert.AreEqual(expectedValue.GetNBool("AS:M"), message.AirborneVelocity.AirspeedExceeded, failMessage); break;
                        case "AirspeedIsTrueAirspeed":              Assert.AreEqual(expectedValue.GetNBool("AST"), message.AirborneVelocity.AirspeedIsTrueAirspeed, failMessage); break;
                        case "AltitudesAreMeanSeaLevel":            Assert.AreEqual(expectedValue.GetNBool("VMSL"), message.TargetStateAndStatus.Version1.AltitudesAreMeanSeaLevel, failMessage); break;
                        case "BarometricAltitude":                  Assert.AreEqual(expectedValue.GetNInt("BA"), message.AirbornePosition.BarometricAltitude, failMessage); break;
                        case "BarometricPressureSetting":           Assert.AreEqual(expectedValue.GetNFloat("QNH"), message.TargetStateAndStatus.Version2.BarometricPressureSetting, failMessage); break;
                        case "ChangeOfIntent":                      Assert.AreEqual(expectedValue.GetNBool("IC"), message.AirborneVelocity.ChangeOfIntent, failMessage); break;
                        case "CompactPosition":                     Assert.AreEqual(expectedValue.GetString("CPR"), cpr == null ? null : cpr.ToString(), failMessage); break;
                        case "EmergencyState":                      Assert.AreEqual(expectedValue.GetEnum<EmergencyState>("ES"), emergencyState, failMessage); break;
                        case "EmergencyStatus":                     if(message.AircraftStatus.AircraftStatusType != AircraftStatusType.EmergencyStatus) Assert.IsNull(message.AircraftStatus.EmergencyStatus); break;
                        case "EmitterCategory":                     Assert.AreEqual(GetExpectedEmitterCategory(expectedValue), message.IdentifierAndCategory.EmitterCategory, failMessage); break;
                        case "FormattedThreatIcao24":               break;
                        case "GeometricAltitude":                   Assert.AreEqual(expectedValue.GetNInt("GA"), message.AirbornePosition.GeometricAltitude, failMessage); break;
                        case "GeometricAltitudeDelta":              Assert.AreEqual(expectedValue.GetNShort("DBA"), message.AirborneVelocity.GeometricAltitudeDelta, failMessage); break;
                        case "GeometricAltitudeDeltaExceeded":      Assert.AreEqual(expectedValue.GetNBool("DBA:M"), message.AirborneVelocity.GeometricAltitudeDeltaExceeded, failMessage); break;
                        case "GroundSpeed":                         Assert.AreEqual(expectedValue.GetNDouble("GSPD"), message.SurfacePosition.GroundSpeed, failMessage); break;
                        case "GroundSpeedExceeded":                 Assert.AreEqual(expectedValue.GetNBool("GSPD:M"), message.SurfacePosition.GroundSpeedExceeded, failMessage); break;
                        case "GroundTrack":                         Assert.AreEqual(expectedValue.GetNDouble("GTRK"), message.SurfacePosition.GroundTrack, failMessage); break;
                        case "Gva":                                 Assert.AreEqual(expectedValue.GetNByte("GVA"), message.AircraftOperationalStatus.Gva, failMessage); break;
                        case "Heading":                             Assert.AreEqual(expectedValue.GetNDouble("HDG"), message.AirborneVelocity.Heading, failMessage); break;
                        case "HorizontalDataSource":                Assert.AreEqual(expectedValue.GetEnum<HorizontalDataSource>("HDS"), message.TargetStateAndStatus.Version1.HorizontalDataSource, failMessage); break;
                        case "HorizontalModeIndicator":             Assert.AreEqual(expectedValue.GetEnum<HorizontalModeIndicator>("HMI"), message.TargetStateAndStatus.Version1.HorizontalModeIndicator, failMessage); break;
                        case "HorizontalReferenceIsMagneticNorth":  Assert.AreEqual(expectedValue.GetNBool("HRD"), message.AircraftOperationalStatus.HorizontalReferenceIsMagneticNorth, failMessage); break;
                        case "HorizontalVelocityError":             Assert.AreEqual(expectedValue.GetNFloat("NAC"), message.AirborneVelocity.HorizontalVelocityError, failMessage); break;
                        case "Identification":                      Assert.AreEqual(expectedValue.GetString("ID"), message.IdentifierAndCategory.Identification, failMessage); break;
                        case "IdentifierAndCategory":               break;
                        case "IsAltitudeHoldActive":                Assert.AreEqual(expectedValue.GetNBool("ALTH"), message.TargetStateAndStatus.Version2.IsAltitudeHoldActive, failMessage); break;
                        case "IsApproachModeActive":                Assert.AreEqual(expectedValue.GetNBool("APP"), message.TargetStateAndStatus.Version2.IsApproachModeActive, failMessage); break;
                        case "IsAutopilotEngaged":                  Assert.AreEqual(expectedValue.GetNBool("APE"), message.TargetStateAndStatus.Version2.IsAutopilotEngaged, failMessage); break;
                        case "IsLnavEngaged":                       Assert.AreEqual(expectedValue.GetNBool("LNAV"), message.TargetStateAndStatus.Version2.IsLnavEngaged, failMessage); break;
                        case "IsRebroadcast":                       Assert.AreEqual(expectedValue.GetNBool("ADSR"), isRebroadcast, failMessage); break;
                        case "IsReversing":                         Assert.AreEqual(expectedValue.GetNBool("REV"), message.SurfacePosition.IsReversing, failMessage); break;
                        case "IsTcasOperational":                   Assert.AreEqual(expectedValue.GetNBool("TCOP"), message.TargetStateAndStatus.Version2.IsTcasOperational, failMessage); break;
                        case "IsVnavEngaged":                       Assert.AreEqual(expectedValue.GetNBool("VNAV"), message.TargetStateAndStatus.Version2.IsVnavEngaged, failMessage); break;
                        case "LateralAxisGpsOffset":                Assert.AreEqual(expectedValue.GetNShort("GLAT"), message.AircraftOperationalStatus.LateralAxisGpsOffset, failMessage); break;
                        case "LongitudinalAxisGpsOffset":           Assert.AreEqual(expectedValue.GetNByte("GLNG"), message.AircraftOperationalStatus.LongitudinalAxisGpsOffset, failMessage); break;
                        case "MaximumLength":                       Assert.AreEqual(expectedValue.GetNFloat("MLN"), message.AircraftOperationalStatus.MaximumLength, failMessage); break;
                        case "MaximumWidth":                        Assert.AreEqual(expectedValue.GetNFloat("MWD"), message.AircraftOperationalStatus.MaximumWidth, failMessage); break;
                        case "MessageFormat":                       Assert.AreEqual(worksheet.ParseEnum<MessageFormat>("MessageFormat"), message.MessageFormat, failMessage); break;
                        case "ModeSMessage":                        Assert.AreSame(_ModeSMessage, message.ModeSMessage, failMessage); break;
                        case "MultipleThreatEncounter":             Assert.AreEqual(expectedValue.GetNBool("MTE"), message.AircraftStatus.TcasResolutionAdvisory.MultipleThreatEncounter, failMessage); break;
                        case "MultipleThreatResolutionAdvisory":    Assert.AreEqual(expectedValue.GetNShort("ARA-M", true), (short?)message.AircraftStatus.TcasResolutionAdvisory.MultipleThreatResolutionAdvisory, failMessage); break;
                        case "NacP":                                Assert.AreEqual(expectedValue.GetNByte("NACP"), nacP, failMessage); break;
                        case "NicA":                                Assert.AreEqual(expectedValue.GetNByte("NICA"), message.AircraftOperationalStatus.NicA, failMessage); break;
                        case "NicB":                                Assert.AreEqual(expectedValue.GetNByte("NICB"), message.AirbornePosition.NicB, failMessage); break;
                        case "NicC":                                Assert.AreEqual(expectedValue.GetNByte("NICC"), message.AircraftOperationalStatus.NicC, failMessage); break;
                        case "NicBaro":                             Assert.AreEqual(expectedValue.GetNBool("NICBA"), nicBaro, failMessage); break;
                        case "OperationalMode":                     Assert.AreEqual(expectedValue.GetNInt("OM", true), (int?)message.AircraftOperationalStatus.OperationalMode, failMessage); break;
                        case "PositionTimeIsExact":                 Assert.AreEqual(expectedValue.GetNBool("TI"), posTime, failMessage); break;
                        case "ResolutionAdvisoryComplement":        Assert.AreEqual(expectedValue.GetNByte("RAC", true), (byte?)message.AircraftStatus.TcasResolutionAdvisory.ResolutionAdvisoryComplement, failMessage); break;
                        case "ResolutionAdvisoryTerminated":        Assert.AreEqual(expectedValue.GetNBool("RAT"), message.AircraftStatus.TcasResolutionAdvisory.ResolutionAdvisoryTerminated, failMessage); break;
                        case "SelectedAltitude":                    Assert.AreEqual(expectedValue.GetNInt("ALT"), message.TargetStateAndStatus.Version2.SelectedAltitude, failMessage); break;
                        case "SelectedAltitudeIsFms":               Assert.AreEqual(expectedValue.GetNBool("ALTF"), message.TargetStateAndStatus.Version2.SelectedAltitudeIsFms, failMessage); break;
                        case "SelectedHeading":                     Assert.AreEqual(expectedValue.GetNDouble("HDG"), message.TargetStateAndStatus.Version2.SelectedHeading, failMessage); break;
                        case "Sil":                                 Assert.AreEqual(expectedValue.GetNByte("SIL"), sil, failMessage); break;
                        case "SilSupplement":                       Assert.AreEqual(expectedValue.GetNBool("SILP"), silSupplement, failMessage); break;
                        case "SingleThreatResolutionAdvisory":      Assert.AreEqual(expectedValue.GetNShort("ARA-S", true), (short?)message.AircraftStatus.TcasResolutionAdvisory.SingleThreatResolutionAdvisory, failMessage); break;
                        case "Squawk":                              Assert.AreEqual(expectedValue.GetNShort("SQK"), message.AircraftStatus.EmergencyStatus.Squawk, failMessage); break;
                        case "SurfacePositionAngleIsTrack":         Assert.AreEqual(expectedValue.GetNBool("SPT"), message.AircraftOperationalStatus.SurfacePositionAngleIsTrack, failMessage); break;
                        case "SurfaceCapability":                   Assert.AreEqual(expectedValue.GetNInt("SC", true), (int?)message.AircraftOperationalStatus.SurfaceCapability, failMessage); break;
                        case "SurfacePosition":                     break;
                        case "SurveillanceStatus":                  Assert.AreEqual(expectedValue.GetEnum<SurveillanceStatus>("SS"), message.AirbornePosition.SurveillanceStatus, failMessage); break;
                        case "SystemDesignAssurance":               Assert.AreEqual(expectedValue.GetEnum<SystemDesignAssurance>("SDA"), message.AircraftOperationalStatus.SystemDesignAssurance, failMessage); break;
                        case "TargetAltitude":                      Assert.AreEqual(expectedValue.GetNInt("ALT"), message.TargetStateAndStatus.Version1.TargetAltitude, failMessage); break;
                        case "TargetAltitudeCapability":            Assert.AreEqual(expectedValue.GetEnum<TargetAltitudeCapability>("TAC"), message.TargetStateAndStatus.Version1.TargetAltitudeCapability, failMessage); break;
                        case "TargetHeading":                       Assert.AreEqual(expectedValue.GetNShort("HDG"), message.TargetStateAndStatus.Version1.TargetHeading, failMessage); break;
                        case "TargetHeadingIsTrack":                Assert.AreEqual(expectedValue.GetNBool("HDG-T"), message.TargetStateAndStatus.Version1.TargetHeadingIsTrack, failMessage); break;
                        case "TargetStateAndStatus":                break;
                        case "TargetStateAndStatusType":            Assert.AreEqual(expectedValue.GetEnum<TargetStateAndStatusType>("TST"), message.TargetStateAndStatus.TargetStateAndStatusType, failMessage); break;
                        case "TcasCapabilityMode":                  Assert.AreEqual(expectedValue.GetEnum<TcasCapabilityMode>("TCC"), message.TargetStateAndStatus.Version1.TcasCapabilityMode, failMessage); break;
                        case "TcasResolutionAdvisory":              if(message.AircraftStatus.AircraftStatusType != AircraftStatusType.TcasResolutionAdvisoryBroadcast) Assert.IsNull(message.AircraftStatus.TcasResolutionAdvisory); break;
                        case "ThreatAltitude":                      Assert.AreEqual(expectedValue.GetNInt("TID-A"), message.AircraftStatus.TcasResolutionAdvisory.ThreatAltitude, failMessage); break;
                        case "ThreatBearing":                       Assert.AreEqual(expectedValue.GetNShort("TID-B"), message.AircraftStatus.TcasResolutionAdvisory.ThreatBearing, failMessage); break;
                        case "ThreatIcao24":                        Assert.AreEqual(expectedValue.GetNInt("TID", true), message.AircraftStatus.TcasResolutionAdvisory.ThreatIcao24, failMessage); break;
                        case "ThreatRange":                         Assert.AreEqual(expectedValue.GetNFloat("TID-R"), message.AircraftStatus.TcasResolutionAdvisory.ThreatRange, failMessage); break;
                        case "ThreatRangeExceeded":                 Assert.AreEqual(expectedValue.GetNBool("TID-R:M"), message.AircraftStatus.TcasResolutionAdvisory.ThreatRangeExceeded, failMessage); break;
                        case "Type":                                Assert.AreEqual(worksheet.Byte("Type"), message.Type, failMessage); break;
                        case "VectorVelocity":                      Assert.AreEqual(expectedValue.GetString("VV"), message.AirborneVelocity.VectorVelocity == null ? null : message.AirborneVelocity.VectorVelocity.ToString(), failMessage); break;
                        case "VelocityType":                        Assert.AreEqual(expectedValue.GetEnum<VelocityType>("VT"), message.AirborneVelocity.VelocityType, failMessage); break;
                        case "Version1":                            if(message.TargetStateAndStatus.TargetStateAndStatusType != TargetStateAndStatusType.Version1) Assert.IsNull(message.TargetStateAndStatus.Version1); break;
                        case "Version2":                            if(message.TargetStateAndStatus.TargetStateAndStatusType != TargetStateAndStatusType.Version2) Assert.IsNull(message.TargetStateAndStatus.Version2); break;
                        case "VerticalDataSource":                  Assert.AreEqual(expectedValue.GetEnum<VerticalDataSource>("VDS"), message.TargetStateAndStatus.Version1.VerticalDataSource, failMessage); break;
                        case "VerticalModeIndicator":               Assert.AreEqual(expectedValue.GetEnum<VerticalModeIndicator>("VMI"), message.TargetStateAndStatus.Version1.VerticalModeIndicator, failMessage); break;
                        case "VerticalRate":                        Assert.AreEqual(expectedValue.GetNInt("VSI"), message.AirborneVelocity.VerticalRate, failMessage); break;
                        case "VerticalRateExceeded":                Assert.AreEqual(expectedValue.GetNBool("VSI:M"), message.AirborneVelocity.VerticalRateExceeded, failMessage); break;
                        case "VerticalRateIsBarometric":            Assert.AreEqual(expectedValue.GetNBool("SBV"), message.AirborneVelocity.VerticalRateIsBarometric, failMessage); break;
                        default:                                    Assert.Fail("Code needs to be added to check the {0} property", messageProperty.Name); break;
                    }
                }
            }

            Assert.AreNotEqual(0, countTestsPerformed, "DF{0}/CF{1}/AF{2} is not valid, no tests were performed", worksheet.String("DF"), worksheet.String("CF"), worksheet.String("AF"));
        }
        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 Plugin_Flight_Updates_Status_Bool_Values_Correctly()
        {
            // These are the Flight record fields that start with "Had".
            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 messageProperty = typeof(BaseStationMessage).GetProperty(worksheet.String("MsgProperty"));
            for(int i = 0;i < worksheet.Int("Count");++i) {
                var message = new BaseStationMessage() { Icao24 = "Z", MessageType = BaseStationMessageType.Transmission, TransmissionType = BaseStationTransmissionType.AirToAir };

                var valueText = worksheet.EString(String.Format("MsgValue{0}", i + 1));
                messageProperty.SetValue(message, TestUtilities.ChangeType(valueText, messageProperty.PropertyType, CultureInfo.InvariantCulture), null);

                _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());

            var propertyName = worksheet.String("FlightProperty");
            var flightProperty = typeof(BaseStationFlight).GetProperty(propertyName);
            var flightValue = worksheet.EString("FlightValue");

            var expectedValue = TestUtilities.ChangeType(flightValue, flightProperty.PropertyType, CultureInfo.InvariantCulture);
            var actualValue = flightProperty.GetValue(flight, null);

            Assert.AreEqual(expectedValue, actualValue, propertyName);
        }
        public void Aircraft_UpdateCoordinates_Resets_Coordinates_If_Aircraft_Looks_To_Be_Moving_Impossibly_Quickly()
        {
            // Some aircraft's transponders report the wrong position. Further, some radios misinterpret position updates at
            // extreme ranges. We can guess the position is wrong if the position and timing of two updates would require the
            // aircraft to be moving at incredibly high speeds. When this is detected we should reset the trails, otherwise the
            // user sees long lines drawn across the map, or a scribble effect if the transponder is just reporting nonsense.

            var worksheet = new ExcelWorksheetData(TestContext);

            var time = DateTime.UtcNow;
            var shortSeconds = 24 * 60 * 60; // seconds in a day

            _Aircraft.DataVersion = time.Ticks;
            _Aircraft.Latitude = worksheet.Float("Lat1");
            _Aircraft.Longitude = worksheet.Float("Lng1");
            _Aircraft.Track = 1;
            _Aircraft.UpdateCoordinates(time, shortSeconds);

            int milliseconds = worksheet.Int("Milliseconds");

            time = time.AddMilliseconds(milliseconds);
            _Aircraft.DataVersion = time.Ticks;
            _Aircraft.Latitude = worksheet.Float("Lat2");
            _Aircraft.Longitude = worksheet.Float("Lng2");
            _Aircraft.Track = 2;
            _Aircraft.UpdateCoordinates(time, shortSeconds);

            if(!worksheet.Bool("ResetTrail")) {
                if(milliseconds >= 1000) {
                    Assert.AreEqual(2, _Aircraft.FullCoordinates.Count);
                    Assert.AreEqual(2, _Aircraft.ShortCoordinates.Count);
                } else {
                    Assert.AreEqual(1, _Aircraft.FullCoordinates.Count);
                    Assert.AreEqual(1, _Aircraft.ShortCoordinates.Count);
                    Assert.AreEqual(1, _Aircraft.FullCoordinates[0].Heading);
                    Assert.AreEqual(1, _Aircraft.ShortCoordinates[0].Heading);
                }
            } else {
                if(milliseconds < 1000) {
                    Assert.AreEqual(0, _Aircraft.FullCoordinates.Count);
                    Assert.AreEqual(0, _Aircraft.ShortCoordinates.Count);
                } else {
                    Assert.AreEqual(1, _Aircraft.FullCoordinates.Count);
                    Assert.AreEqual(1, _Aircraft.ShortCoordinates.Count);
                    Assert.AreEqual(2, _Aircraft.FullCoordinates[0].Heading);
                    Assert.AreEqual(2, _Aircraft.ShortCoordinates[0].Heading);
                }
            }
        }
        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 ConnectionSessionLogPresenter_Clicking_ShowSessions_Triggers_Validation()
        {
            var worksheet = new ExcelWorksheetData(TestContext);

            _Presenter.Initialise(_View.Object);
            _View.Object.StartDate = worksheet.DateTime("StartDate");
            _View.Object.EndDate = worksheet.DateTime("EndDate");

            IEnumerable<ValidationResult> validationResults = null;
            _View.Setup(v => v.ShowValidationResults(It.IsAny<IEnumerable<ValidationResult>>())).Callback((IEnumerable<ValidationResult> results) => {
                validationResults = results;
            });

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

            Assert.IsNotNull(validationResults);
            Assert.AreEqual(worksheet.Int("CountErrors"), validationResults.Count());
            if(validationResults.Count() > 0) {
                Assert.IsTrue(validationResults.Where(r => r.Field == worksheet.ParseEnum<ValidationField>("Field") &&
                                                           r.Message == worksheet.String("Message") &&
                                                           r.IsWarning == worksheet.Bool("IsWarning")).Any());
            }
        }
        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());
            }
        }
        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 PluginSettingsStorage_Load_Returns_Parsed_File_Content_If_File_Is_Present()
        {
            var worksheet = new ExcelWorksheetData(TestContext);
            var lines = new List<string>();
            foreach(var line in worksheet.EString("Lines").Split('\n')) {
                lines.Add(line);
            }
            _Provider.Setup(p => p.FileReadAllLines(It.Is<string>(n => n.Equals(_ExpectedFileName, StringComparison.OrdinalIgnoreCase)))).Returns(lines.ToArray());

            var settings = _Storage.Load();

            Assert.AreEqual(worksheet.Int("Count"), settings.Values.Count);
            for(int i = 1;i <= settings.Values.Count;++i) {
                Assert.AreEqual(worksheet.EString(String.Format("Key{0}", i)), settings.Values.Keys[i-1]);
                Assert.AreEqual(worksheet.EString(String.Format("Value{0}", i)), settings.Values[i-1]);
            }
        }