public void GetPropertyName_ShouldThrowArgumentException_GivenMethodExpression()
 {
     // Arrange
     // Act
     // Assert
     Assert.That(() => PropertyFromExpression.GetPropertyName <ClassWithProperty, int>(c => c.IntegerMethod()), Throws.ArgumentException);
 }
        public void GetPropertyName_ShouldReturnPropertyName_GivenPropertyExpression()
        {
            // Arrange
            // Act
            var actual = PropertyFromExpression.GetPropertyName <ClassWithProperty, int>(c => c.IntegerProperty);

            // Assert
            Assert.That(actual, Is.EqualTo(nameof(ClassWithProperty.IntegerProperty)));
        }
        public static bool ShouldThrow <T, TDuplicateKey>(IEnumerable <T> implementations, Expression <Func <T, TDuplicateKey> > duplicateKeySelector,
                                                          Func <TDuplicateKey, string> duplicateKeyFormatter, out string exceptionMessage) where T : notnull
        {
            exceptionMessage = string.Empty;

            var groupsOfDuplicates = implementations
                                     .GroupBy(duplicateKeySelector.Compile())
                                     .Where(g => g.Count() > 1)
                                     .ToList();

            var duplicatesFound = groupsOfDuplicates.Any();

            if (duplicatesFound)
            {
                var stringBuilder = new StringBuilder();
                var propertyName  = PropertyFromExpression.GetPropertyName(duplicateKeySelector);

                stringBuilder.AppendLine(
                    $"Found multiple implementations of {typeof(T).FullName} for the same value of {propertyName}. Only one implementation per {propertyName} is allowed.");

                foreach (var duplicates in groupsOfDuplicates)
                {
                    var keyValue = duplicateKeyFormatter(duplicates.Key);
                    stringBuilder.AppendLine($"Duplicates for {propertyName} \"{keyValue}\":");

                    foreach (var implementation in duplicates)
                    {
                        stringBuilder.AppendLine($"- {implementation.GetType().FullName}");
                    }
                }

                exceptionMessage = stringBuilder.ToString();
            }

            return(duplicatesFound);
        }