Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Parsing Latitude and Longitude Information

, 21 Feb 2012 CPOL
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)

Share

About the Author

Samuel Cragg

United Kingdom United Kingdom
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141030.1 | Last Updated 21 Feb 2012
Article Copyright 2011 by Samuel Cragg
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid