Click here to Skip to main content
15,882,163 members
Articles / General Programming / Regular Expressions

Parsing Latitude and Longitude Information

Rate me:
Please Sign up or sign in to vote.
4.73/5 (24 votes)
21 Feb 2012CPOL9 min read 93K   2K   74  
Parses user input and extracts latitude and longitude information, taking into account the user's language and regional settings
using System;
using Geospatial;
using NUnit.Framework;
using Linq = System.Linq;
using System.Collections.Generic;

namespace UnitTests
{
    [TestFixture]
    public sealed class LocationCollectionTest // Needs to be public for the XmlSerializer test
    {
        private const double Delta = 0.000001;

        [Test]
        public void TestAdd()
        {
            var collection = new LocationCollection();
            Assert.Throws<ArgumentNullException>(() => collection.Add(null));

            var location = TestHelpers.CreateLocation(0, 0);
            Assert.AreEqual(0, collection.Count);
            collection.Add(location);
            Assert.AreEqual(1, collection.Count);

            // Make sure we can add the same Location more than once
            collection.Add(location);
            Assert.AreEqual(2, collection.Count);

            // Make sure the compiler call to Add also works
            var initialised = new LocationCollection
            {
                TestHelpers.CreateLocation(0, 0),
                TestHelpers.CreateLocation(1, 1)
            };
            Assert.AreEqual(2, initialised.Count);
        }

        [Test]
        public void TestClear()
        {
            var collection = new LocationCollection
            {
                TestHelpers.CreateLocation(0, 0),
                TestHelpers.CreateLocation(1, 1)
            };

            Assert.AreEqual(2, collection.Count);
            collection.Clear();
            Assert.AreEqual(0, collection.Count);

            // Make sure we can clear an empty collection
            Assert.DoesNotThrow(() => collection.Clear());
        }

        [Test]
        public void TestContains()
        {
            var location = TestHelpers.CreateLocation(0, 0);
            var collection = new LocationCollection
            {
                location,
                TestHelpers.CreateLocation(1, 1)
            };

            Assert.IsFalse(collection.Contains(null)); // Make sure it doesn't throw
            Assert.IsFalse(collection.Contains(TestHelpers.CreateLocation(0, 1)));
            Assert.IsFalse(collection.Contains(TestHelpers.CreateLocation(0, 0, 0))); // Test the Altitude!

            Assert.IsTrue(collection.Contains(location));

            // Check it finds the same location (even if it doesn't have the same reference)
            Assert.IsTrue(collection.Contains(TestHelpers.CreateLocation(1, 1)));
        }

        [Test]
        public void TestCopyTo()
        {
            const int ElementCount = 100;

            var source = new LocationCollection();
            for (int i = 0; i < ElementCount; i++)
            {
                source.Add(TestHelpers.CreateLocation(0, 0, 0));
            }

            var destination = new Location[ElementCount];

            Assert.Throws<ArgumentNullException>(() => source.CopyTo(null, 0));
            Assert.Throws<ArgumentOutOfRangeException>(() => source.CopyTo(destination, int.MinValue));
            Assert.Throws<ArgumentOutOfRangeException>(() => source.CopyTo(destination, -1));

            Assert.Throws<ArgumentException>(() => source.CopyTo(destination, int.MaxValue));
            Assert.Throws<ArgumentException>(() => source.CopyTo(destination, ElementCount - 1));
            Assert.Throws<ArgumentException>(() => source.CopyTo(destination, 1));

            // Make sure it's not changed the destination yet
            foreach (var element in destination)
            {
                Assert.IsNull(element);
            }

            source.CopyTo(destination, 0);
            CompareCollections(source, destination);
        }

        [Test]
        public void TestCountAndGetEnumerator()
        {
            var collection = new LocationCollection();
            Assert.AreEqual(0, collection.Count);

            // We use the Linq Select extension to force the ICollection into
            // an IEnumerable, which disables the Count extension from 'optimizing'
            // and using the ICollection.Count property. Effectivly, this forces
            // an actual iteration of all the collection object (thus testing
            // the GetEnumerator method).
            //
            // Also, fully qualify the Linq methods so we don't need a using
            // directive and ensures that the other tests don't pick the
            // the wrong method by accident.
            Assert.AreEqual(0, Linq.Enumerable.Count(Linq.Enumerable.Select(collection, x => x)));

            const int ElementCount = 100;
            for (int i = 0; i < ElementCount; i++)
            {
                collection.Add(TestHelpers.CreateLocation(0, 0));
            }
            Assert.AreEqual(ElementCount, collection.Count);
            Assert.AreEqual(ElementCount, Linq.Enumerable.Count(Linq.Enumerable.Select(collection, x => x)));
        }

        [Test]
        public void TestRemove()
        {
            var location = TestHelpers.CreateLocation(0, 0);
            var collection = new LocationCollection
            {
                location,
                TestHelpers.CreateLocation(1, 1)
            };

            Assert.AreEqual(2, collection.Count);
            Assert.IsFalse(collection.Remove(null)); // Make sure it doesn't throw
            Assert.IsFalse(collection.Remove(TestHelpers.CreateLocation(0, 1)));
            Assert.AreEqual(2, collection.Count); // Make sure it really hasn't changed

            // Check it finds the same location (even if it doesn't have the same reference)
            Assert.IsTrue(collection.Remove(TestHelpers.CreateLocation(1, 1)));
            Assert.AreEqual(1, collection.Count);
            Assert.IsFalse(collection.Remove(TestHelpers.CreateLocation(1, 1)));
            Assert.AreEqual(1, collection.Count);

            Assert.IsTrue(collection.Remove(location));
            Assert.AreEqual(0, collection.Count);
        }

        [Test]
        public void TestXmlSerialization()
        {
            var data = new XmlSerializerTestStruct
            {
                Collection = new LocationCollection
                {
                    TestHelpers.CreateLocation(12, 34, 56),
                    TestHelpers.CreateLocation(12, 34),
                    TestHelpers.CreateLocation(12, -34, 56)
                },
                Name = "Test Data"
            };
            var deserialized = TestHelpers.Serialize(data);

            Assert.AreEqual(data.Name, deserialized.Name);
            CompareCollections(data.Collection, deserialized.Collection);

            var empty = new LocationCollection();
            CompareCollections(TestHelpers.Serialize(empty), empty);
        }

        // Can't use anonymous classes as they don't have a parameterless constructor
        public struct XmlSerializerTestStruct
        {
            public LocationCollection Collection;
            public string Name;
        }

        private void CompareCollections(IEnumerable<Location> first, IEnumerable<Location> second)
        {
            using (IEnumerator<Location> a = first.GetEnumerator(), b = second.GetEnumerator())
            {
                while (true)
                {
                    if (a.MoveNext())
                    {
                        Assert.IsTrue(b.MoveNext());
                        TestHelpers.AssertLocationsAreEqual(a.Current, b.Current);
                    }
                    else
                    {
                        Assert.IsFalse(b.MoveNext());
                        break;
                    }
                }
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions