As a continuation to my recent rant about the differences between programmers and developers and how programmers love to code and … well, everything it is mentioned in that post, I felt like sharing a little bit of fun I had with this stackoverflow question.

Since it had already been answered and actually there was a little debate going on about the pros and cons of the accepted answer I was about to close it and look for something else when I decided to have a little bit of fun and make the solution generic.

Not like it was difficult, after a couple of minutes I had this:

    public class PropertyValidator
    {
        public bool Validate<T, TResult>(IEnumerable<T> list, Func<T, TResult> expression)
        {
            return list.Select(expression).Distinct().Count() <= 1;
        }
    }

But the fun didn’t end there, since this was not needed in what I was working on I had to demonstrate that it worked by other means, what could those means possibly be? You guessed it, unit tests!

    [TestClass]
    public class SameValueInPropertyValidatorTests
    {
        private PropertyValidator _validator;

        [TestInitialize]
        public void Initialize()
        {
            _validator = new PropertyValidator();
        }

        [TestMethod]
        public void ReturnsTrueIfListIsEmpty()
        {
            var list = new List<string>();
            Func<string, string> expression = x => x;

            var result = _validator.Validate(list, expression);

            Assert.IsTrue(result);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForStrings()
        {
            var list = new List<string> {"1", "1", "1", "1", "1", "1"};
            Func<string, string> expression = x => x;

            var result = _validator.Validate(list, expression);

            Assert.IsTrue(result);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForStrings()
        {
            var list = new List<string> { "1", "1", "2", "1", "1", "1" };
            Func<string, string> expression = x => x;

            var result = _validator.Validate(list, expression);

            Assert.IsFalse(result);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForKeyValuePair()
        {
            var list = new List<KeyValuePair<string, int>>
            {
                new KeyValuePair<string, int>("any1", 1),
                new KeyValuePair<string, int>("any2", 1),
                new KeyValuePair<string, int>("any3", 1),
                new KeyValuePair<string, int>("any4", 1),
            };

            Func<KeyValuePair<string, int>, int> expression = x => x.Value;

            var result = _validator.Validate(list, expression);

            Assert.IsTrue(result);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForKeyValuePair()
        {
            var list = new List<KeyValuePair<string, int>>
            {
                new KeyValuePair<string, int>("any1", 1),
                new KeyValuePair<string, int>("any2", 1),
                new KeyValuePair<string, int>("any3", 456),
                new KeyValuePair<string, int>("any4", 1),
            };

            Func<KeyValuePair<string, int>, int> expression = x => x.Value;

            var result = _validator.Validate(list, expression);

            Assert.IsFalse(result);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForEnumProperty()
        {
            var list = new List<Car>
            {
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
            };

            Func<Car, Colors> expression = x => x.Color;

            var result = _validator.Validate(list, expression);

            Assert.IsTrue(result);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForEnumProperty()
        {
            var list = new List<Car>
            {
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Black},
                new Car {Color = Colors.Red},
            };

            Func<Car, Colors> expression = x => x.Color;

            var result = _validator.Validate(list, expression);

            Assert.IsFalse(result);
        }

    }

And since we were on a roll, why not remove the duplication by creating generic methods to assert the results:

    [TestClass]
    public class SameValueInPropertyValidatorTests
    {
        private PropertyValidator _validator;

        [TestInitialize]
        public void Initialize()
        {
            _validator = new PropertyValidator();
        }

        [TestMethod]
        public void ReturnsTrueIfListIsEmpty()
        {
            var list = new List<string>();
            Func<string, string> expression = x => x;

            AssertIsTrue(list, expression);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForStrings()
        {
            var list = new List<string> { "1", "1", "1", "1", "1", "1" };
            Func<string, string> expression = x => x;

            AssertIsTrue(list, expression);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForStrings()
        {
            var list = new List<string> { "1", "1", "2", "1", "1", "1" };
            Func<string, string> expression = x => x;

            AssertIsFalse(list, expression);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForKeyValuePair()
        {
            var list = new List<KeyValuePair<string, int>>
            {
                new KeyValuePair<string, int>("any1", 1),
                new KeyValuePair<string, int>("any2", 1),
                new KeyValuePair<string, int>("any3", 1),
                new KeyValuePair<string, int>("any4", 1),
            };

            Func<KeyValuePair<string, int>, int> expression = x => x.Value;

            AssertIsTrue(list, expression);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForKeyValuePair()
        {
            var list = new List<KeyValuePair<string, int>>
            {
                new KeyValuePair<string, int>("any1", 1),
                new KeyValuePair<string, int>("any2", 1),
                new KeyValuePair<string, int>("any3", 456),
                new KeyValuePair<string, int>("any4", 1),
            };

            Func<KeyValuePair<string, int>, int> expression = x => x.Value;

            AssertIsFalse(list, expression);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForEnumProperty()
        {
            var list = new List<Car>
            {
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
            };

            Func<Car, Colors> expression = x => x.Color;

            AssertIsTrue(list, expression);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForEnumProperty()
        {
            var list = new List<Car>
            {
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Black},
                new Car {Color = Colors.Red},
            };

            Func<Car, Colors> expression = x => x.Color;

            AssertIsFalse(list, expression);
        }

        private void AssertIsTrue<T, TResult>(IEnumerable<T> list, Func<T, TResult> expression)
        {
            var result = _validator.Validate(list, expression);

            Assert.IsTrue(result);
        }    

        private void AssertIsFalse<T, TResult>(IEnumerable<T> list, Func<T, TResult> expression)
        {
            var result = _validator.Validate(list, expression);

            Assert.IsFalse(result);
        }    
    }

Not exactly a break through discovery or even a coding kata but still it was a cute exercise for me to kill some time.

Would you like to share your favorite exercises or your sources of inspiration for coding research? I’d love to hear about them.