/// <summary>
        /// Adds the rule to include or exclude the <paramref name="methodName"/>.
        /// </summary>
        /// <param name="filter">The <see cref="Regex"/> filter.</param>
        /// <param name="parameterName">The parameter name.</param>
        /// <param name="include">A value indicating whether this is a include or exclude rule.</param>
        /// <param name="typeFullName">The <see cref="Type.FullName"/> of the <see cref="Type"/>.</param>
        /// <param name="methodName">The method name.</param>
        /// <returns>The <paramref name="filter"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="filter"/> or <paramref name="parameterName"/>
        /// parameters are <see langword="null"/>.</exception>
        private static IRegexFilter AddParameterRule(
            this IRegexFilter filter,
            string parameterName,
            bool include,
            string typeFullName = null,
            string methodName   = null)
        {
            if (filter == null)
            {
                throw new ArgumentNullException(nameof(filter));
            }
            if (string.IsNullOrWhiteSpace(parameterName))
            {
                throw new ArgumentNullException(nameof(parameterName));
            }

            string name = string.Concat(include ? "Include " : "Exclude ", parameterName);

            filter.Rules.Add(new RegexRule(
                                 name,
                                 include: include,
                                 type: GetNameRegex(typeFullName),
                                 method: GetNameRegex(methodName),
                                 parameter: GetNameRegex(parameterName)));

            return(filter);
        }
 private static void AssertSingleExcludeAllMethodsRule(IRegexFilter regexFilter)
 {
     RegexRule regexRule = regexFilter.MethodRules.Single();
     Assert.False(regexRule.Include);
     Assert.Null(regexRule.Type);
     Assert.True(regexRule.Method.IsMatch(Guid.NewGuid().ToString()));
 }
        private static void AssertSingleExcludeAllTypesRule(IRegexFilter regexFilter)
        {
            RegexRule regexRule = regexFilter.TypeRules.Single();

            Assert.False(regexRule.Include);
            Assert.Matches(regexRule.Type, Guid.NewGuid().ToString());
        }
 /// <summary>
 /// Excludes the <paramref name="methodName"/> from checks for <see cref="ArgumentNullException"/>.
 /// </summary>
 /// <param name="filter">The <see cref="Regex"/> filter.</param>
 /// <param name="methodName">The method name.</param>
 /// <param name="typeFullName">The <see cref="Type.FullName"/> of the <see cref="Type"/>.</param>
 /// <returns>The <paramref name="filter"/>.</returns>
 /// <exception cref="ArgumentNullException">The <paramref name="filter"/> or <paramref name="methodName"/>
 /// parameters are <see langword="null"/>.</exception>
 public static IRegexFilter ExcludeMethod(
     this IRegexFilter filter,
     string methodName,
     string typeFullName = null)
 {
     return(filter.AddMethodRule(methodName, include: false, typeFullName: typeFullName));
 }
// ReSharper disable UnusedParameter.Local
        private void AssertMethodRule(Func <string, Type, IRegexFilter> addMethod, MethodBase method, Type type, bool expectedInclude)
        {
            IRegexFilter actualFilter = addMethod(method.Name, type);

            int expectedRules = 1;

            if (expectedInclude && type != null)
            {
                expectedRules++;
            }

            Assert.Same(addMethod.Target, actualFilter);
            Assert.Equal(expectedRules, actualFilter.Rules.Count);
            RegexRule addedRule = actualFilter.MethodRules.Single();

            Assert.Equal(expectedInclude, addedRule.Include);
            Assert.NotNull(addedRule.Method);
            Assert.True(addedRule.MatchMethod(type ?? GetType(), method));
            Assert.Null(addedRule.Parameter);

            if (type == null)
            {
                Assert.Null(addedRule.Type);
            }
            else
            {
                Assert.NotNull(addedRule.Type);
                Assert.True(addedRule.MatchType(type));
            }
        }
 /// <summary>
 /// Includes the <paramref name="parameterName"/> for checks for <see cref="ArgumentNullException"/>. Overrides
 /// any parameter rules that may exclude the <paramref name="parameterName"/>.
 /// </summary>
 /// <param name="filter">The <see cref="Regex"/> filter.</param>
 /// <param name="parameterName">The parameter name.</param>
 /// <param name="type">The type.</param>
 /// <param name="methodName">The method name.</param>
 /// <returns>The <paramref name="filter"/>.</returns>
 /// <exception cref="ArgumentNullException">The <paramref name="filter"/> or <paramref name="parameterName"/>
 /// parameters are <see langword="null"/>.</exception>
 public static IRegexFilter IncludeParameter(
     this IRegexFilter filter,
     string parameterName,
     Type type,
     string methodName = null)
 {
     return(filter.IncludeParameter(parameterName, type != null ? type.FullName : null, methodName));
 }
        private static void AssertSingleExcludeAllParametersRule(IRegexFilter regexFilter)
        {
            RegexRule regexRule = regexFilter.ParameterRules.Single();

            Assert.False(regexRule.Include);
            Assert.Null(regexRule.Type);
            Assert.Null(regexRule.Method);
            Assert.Matches(regexRule.Parameter, Guid.NewGuid().ToString());
        }
        /// <summary>
        /// Includes the <paramref name="type"/> for checks for <see cref="ArgumentNullException"/>. Overrides any type
        /// rules that may exclude the <paramref name="type"/>.
        /// </summary>
        /// <param name="filter">The <see cref="Regex"/> filter.</param>
        /// <param name="type">The type.</param>
        /// <returns>The <paramref name="filter"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="filter"/> or <paramref name="type"/> parameters
        /// are <see langword="null"/>.</exception>
        public static IRegexFilter IncludeType(this IRegexFilter filter, Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            return(filter.IncludeType(type.FullName));
        }
 /// <summary>
 /// Excludes the <paramref name="parameterName"/> from checks for <see cref="ArgumentNullException"/>.
 /// </summary>
 /// <param name="filter">The <see cref="Regex"/> filter.</param>
 /// <param name="parameterName">The parameter name.</param>
 /// <param name="typeFullName">The <see cref="Type.FullName"/> of the <see cref="Type"/>.</param>
 /// <param name="methodName">The method name.</param>
 /// <returns>The <paramref name="filter"/>.</returns>
 /// <exception cref="ArgumentNullException">The <paramref name="filter"/> or <paramref name="parameterName"/>
 /// parameters are <see langword="null"/>.</exception>
 public static IRegexFilter ExcludeParameter(
     this IRegexFilter filter,
     string parameterName,
     string typeFullName = null,
     string methodName   = null)
 {
     return(filter.AddParameterRule(
                parameterName,
                include: false,
                typeFullName: typeFullName,
                methodName: methodName));
 }
        /// <summary>
        /// Excludes all types, methods and parameters.
        /// </summary>
        /// <param name="filter">The <see cref="Regex"/> filter.</param>
        /// <returns>The <paramref name="filter"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="filter"/> parameter is
        /// <see langword="null"/>.</exception>
        public static IRegexFilter ExcludeAll(this IRegexFilter filter)
        {
            if (filter == null)
            {
                throw new ArgumentNullException(nameof(filter));
            }

            return
                (filter.ExcludeAllTypes()
                 .ExcludeAllMethods()
                 .ExcludeAllParameters());
        }
        /// <summary>
        /// Excludes all types, methods and parameters.
        /// </summary>
        /// <param name="fixture">The fixture.</param>
        /// <returns>The <paramref name="fixture"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="fixture"/> parameter is <see langword="null"/>.</exception>
        public static IArgumentNullExceptionFixture ExcludeAll(this IArgumentNullExceptionFixture fixture)
        {
            if (fixture == null)
            {
                throw new ArgumentNullException(nameof(fixture));
            }

            IRegexFilter regexFilter = fixture.GetRegexFilter();

            regexFilter.ExcludeAll();

            return(fixture);
        }
        /// <summary>
        /// Includes the <paramref name="methodName"/> for checks for <see cref="ArgumentNullException"/>. Overrides any
        /// method rules that may exclude the <paramref name="methodName"/>.
        /// </summary>
        /// <param name="filter">The <see cref="Regex"/> filter.</param>
        /// <param name="methodName">The method name.</param>
        /// <param name="typeFullName">The type.</param>
        /// <returns>The <paramref name="filter"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="filter"/> or <paramref name="methodName"/>
        /// parameters are <see langword="null"/>.</exception>
        public static IRegexFilter IncludeMethod(
            this IRegexFilter filter,
            string methodName,
            string typeFullName = null)
        {
            // If the type is specified ensure it is included otherwise the
            // method may never be included.
            if (!string.IsNullOrWhiteSpace(typeFullName))
            {
                filter.IncludeType(typeFullName);
            }

            return(filter.AddMethodRule(methodName, include: true, typeFullName: typeFullName));
        }
// ReSharper disable UnusedParameter.Local
        private void AssertTypeRule(Func <Type, IRegexFilter> addMethod, bool expectedInclude)
        {
            IRegexFilter actualFilter = addMethod(GetType());

            Assert.Same(addMethod.Target, actualFilter);
            Assert.Single(actualFilter.Rules);
            RegexRule addedRule = actualFilter.Rules.Single();

            Assert.Equal(expectedInclude, addedRule.Include);
            Assert.NotNull(addedRule.Type);
            Assert.Null(addedRule.Method);
            Assert.Null(addedRule.Parameter);
            Assert.True(addedRule.MatchType(GetType()));
        }
        /// <summary>
        /// Excludes all types, methods and parameters.
        /// </summary>
        /// <param name="filter">The <see cref="Regex"/> filter.</param>
        /// <returns>The <paramref name="filter"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="filter"/> parameter is
        /// <see langword="null"/>.</exception>
        public static IRegexFilter ExcludeAllParameters(this IRegexFilter filter)
        {
            if (filter == null)
            {
                throw new ArgumentNullException(nameof(filter));
            }

            filter.Rules.Add(new RegexRule(
                                 "Exclude all parameters",
                                 include: false,
                                 parameter: MatchAll));

            return(filter);
        }
        public void ExcludeAllParameters()
        {
            // Arrange
            var sut = new RegexFilter();

            // Act
            IRegexFilter result = sut.ExcludeAllParameters();

            // Assert
            Assert.Same(sut, result);
            Assert.Single(sut.Rules);
            RegexRule parameterRule = sut.ParameterRules.Single();

            Assert.Matches(parameterRule.Parameter, Guid.NewGuid().ToString());
        }
        public void ExcludeAllMethods()
        {
            // Arrange
            var sut = new RegexFilter();

            // Act
            IRegexFilter result = sut.ExcludeAllMethods();

            // Assert
            Assert.Same(sut, result);
            Assert.Single(sut.Rules);
            RegexRule methodRule = sut.MethodRules.Single();

            Assert.Matches(methodRule.Method, Guid.NewGuid().ToString());
        }
        /// <summary>
        /// Includes the <paramref name="typeFullName"/> for checks for <see cref="ArgumentNullException"/>.
        /// Overrides any type rules that may exclude the <paramref name="typeFullName"/>.
        /// </summary>
        /// <param name="fixture">The fixture.</param>
        /// <param name="typeFullName">The <see cref="Type.FullName"/> of the <see cref="Type"/>.</param>
        /// <returns>The <paramref name="fixture"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="fixture"/> or <paramref name="typeFullName"/>
        /// parameters are <see langword="null"/>.</exception>
        public static IArgumentNullExceptionFixture IncludeType(this IArgumentNullExceptionFixture fixture, string typeFullName)
        {
            if (fixture == null)
            {
                throw new ArgumentNullException(nameof(fixture));
            }
            if (string.IsNullOrWhiteSpace(typeFullName))
            {
                throw new ArgumentNullException(nameof(typeFullName));
            }

            IRegexFilter regexFilter = fixture.GetRegexFilter();

            regexFilter.IncludeType(typeFullName);

            return(fixture);
        }
        public void ExcludeNone(
            ExcludeAllAttribute sut,
            MethodInfo method)
        {
            // Arrange
            sut.ExclusionType = ExclusionType.None;
            var fixture = new ArgumentNullExceptionFixture(GetType().GetTypeInfo().Assembly);
            IArgNullExCustomization customization = sut.GetCustomization(method);

            // Act
            customization.Customize(fixture);

            // Assert
            IRegexFilter regexFilter = fixture.Filters.OfType <IRegexFilter>().Single();

            Assert.Empty(regexFilter.Rules);
        }
        /// <summary>
        /// Gets the single <see cref="IRegexFilter"/> from the <see cref="IArgumentNullExceptionFixture.Filters"/>.
        /// </summary>
        /// <param name="fixture">The fixture.</param>
        /// <returns>The single <see cref="IRegexFilter"/> from the <see cref="IArgumentNullExceptionFixture.Filters"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="fixture"/> parameter is <see langword="null"/>.</exception>
        /// <exception cref="InvalidOperationException">There are zero of more than one <see cref="IRegexFilter"/> objects in the <see cref="IArgumentNullExceptionFixture.Filters"/>.</exception>
        private static IRegexFilter GetRegexFilter(this IArgumentNullExceptionFixture fixture)
        {
            if (fixture == null)
            {
                throw new ArgumentNullException(nameof(fixture));
            }

            IRegexFilter regexFilter =
                fixture.Filters
                .OfType <IRegexFilter>()
                .SingleOrDefault();

            if (regexFilter == null)
            {
                throw new InvalidOperationException("There is no IRegexFilter in the filters.");
            }

            return(regexFilter);
        }
// ReSharper disable UnusedParameter.Local
        private void AssertParameterRule(Func <string, Type, string, IRegexFilter> addMethod, ParameterInfo parameter, Type type, MethodBase method, bool expectedInclude)
        {
            IRegexFilter actualFilter = addMethod(parameter.Name, type, method == null ? null : method.Name);

            int expectedRules = 1;

            if (expectedInclude && method != null)
            {
                expectedRules++;
            }
            if (expectedInclude && type != null)
            {
                expectedRules++;
            }

            Assert.Same(addMethod.Target, actualFilter);
            Assert.Equal(expectedRules, actualFilter.Rules.Count);
            RegexRule addedRule = actualFilter.ParameterRules.Single();

            Assert.Equal(expectedInclude, addedRule.Include);
            Assert.NotNull(addedRule.Parameter);
            Assert.True(addedRule.MatchParameter(type ?? GetType(), method ?? new Mock <MethodBase>().Object, parameter));

            if (type == null)
            {
                Assert.Null(addedRule.Type);
            }
            else
            {
                Assert.NotNull(addedRule.Type);
                Assert.True(addedRule.MatchType(type));
            }

            if (method == null)
            {
                Assert.Null(addedRule.Method);
            }
            else
            {
                Assert.NotNull(addedRule.Method);
                Assert.True(addedRule.MatchMethod(type ?? GetType(), method));
            }
        }
        public void ExcludeAllMethods(
            ExcludeAllAttribute sut,
            MethodInfo method)
        {
            // Arrange
            sut.ExclusionType = ExclusionType.Methods;
            var fixture = new ArgumentNullExceptionFixture(GetType().GetTypeInfo().Assembly);
            IArgNullExCustomization customization = sut.GetCustomization(method);

            // Act
            customization.Customize(fixture);
            IEnumerable <MethodData> data = fixture.GetData();

            // Assert
            Assert.Empty(data);
            IRegexFilter regexFilter = fixture.Filters.OfType <IRegexFilter>().Single();

            Assert.Single(regexFilter.Rules);
            AssertSingleExcludeAllMethodsRule(regexFilter);
        }
        /// <summary>
        /// Excludes the <paramref name="methodName"/> from checks for <see cref="ArgumentNullException"/>.
        /// </summary>
        /// <param name="fixture">The fixture.</param>
        /// <param name="methodName">The method name.</param>
        /// <param name="typeFullName">The <see cref="Type.FullName"/> of the <see cref="Type"/>.</param>
        /// <returns>The <paramref name="fixture"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="fixture"/> or <paramref name="methodName"/>
        /// parameters are <see langword="null"/>.</exception>
        public static IArgumentNullExceptionFixture ExcludeMethod(
            this IArgumentNullExceptionFixture fixture,
            string methodName,
            string typeFullName = null)
        {
            if (fixture == null)
            {
                throw new ArgumentNullException(nameof(fixture));
            }
            if (string.IsNullOrWhiteSpace(methodName))
            {
                throw new ArgumentNullException(nameof(methodName));
            }

            IRegexFilter regexFilter = fixture.GetRegexFilter();

            regexFilter.ExcludeMethod(methodName, typeFullName);

            return(fixture);
        }
        public void ExcludeAll()
        {
            // Arrange
            var sut = new RegexFilter();

            // Act
            IRegexFilter result = sut.ExcludeAll();

            // Assert
            Assert.Same(sut, result);
            Assert.Equal(3, sut.Rules.Count);
            RegexRule typeRule = sut.TypeRules.Single();

            Assert.Matches(typeRule.Type, Guid.NewGuid().ToString());
            RegexRule methodRule = sut.MethodRules.Single();

            Assert.Matches(methodRule.Method, Guid.NewGuid().ToString());
            RegexRule parameterRule = sut.ParameterRules.Single();

            Assert.Matches(parameterRule.Parameter, Guid.NewGuid().ToString());
        }
        /// <summary>
        /// Includes the <paramref name="parameterName"/> for checks for <see cref="ArgumentNullException"/>. Overrides
        /// any parameter rules that may exclude the <paramref name="parameterName"/>.
        /// </summary>
        /// <param name="filter">The <see cref="Regex"/> filter.</param>
        /// <param name="parameterName">The parameter name.</param>
        /// <param name="typeFullName">The <see cref="Type.FullName"/> of the <see cref="Type"/>.</param>
        /// <param name="methodName">The method name.</param>
        /// <returns>The <paramref name="filter"/>.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="filter"/> or <paramref name="parameterName"/>
        /// parameters are <see langword="null"/>.</exception>
        public static IRegexFilter IncludeParameter(
            this IRegexFilter filter,
            string parameterName,
            string typeFullName = null,
            string methodName   = null)
        {
            // If the method or type type is specified ensure they are included
            // otherwise the parameter may never be included.
            if (!string.IsNullOrWhiteSpace(methodName))
            {
                filter.IncludeMethod(methodName, typeFullName);
            }
            else if (!string.IsNullOrWhiteSpace(typeFullName))
            {
                filter.IncludeType(typeFullName);
            }

            return(filter.AddParameterRule(
                       parameterName,
                       include: true,
                       typeFullName: typeFullName,
                       methodName: methodName));
        }
 /// <summary>
 /// Excludes the <paramref name="methodName"/> from checks for <see cref="ArgumentNullException"/>.
 /// </summary>
 /// <param name="filter">The <see cref="Regex"/> filter.</param>
 /// <param name="methodName">The method name.</param>
 /// <param name="type">The type.</param>
 /// <returns>The <paramref name="filter"/>.</returns>
 /// <exception cref="ArgumentNullException">The <paramref name="filter"/> or <paramref name="methodName"/>
 /// parameters are <see langword="null"/>.</exception>
 public static IRegexFilter ExcludeMethod(this IRegexFilter filter, string methodName, Type type)
 {
     return(filter.ExcludeMethod(methodName, type != null ? type.FullName : null));
 }
 /// <summary>
 /// Includes the <paramref name="typeFullName"/> for checks for <see cref="ArgumentNullException"/>. Overrides
 /// any type rules that may exclude the <paramref name="typeFullName"/>.
 /// </summary>
 /// <param name="filter">The <see cref="Regex"/> filter.</param>
 /// <param name="typeFullName">The <see cref="Type.FullName"/> of the <see cref="Type"/>.</param>
 /// <returns>The <paramref name="filter"/>.</returns>
 /// <exception cref="ArgumentNullException">The <paramref name="filter"/> or <paramref name="typeFullName"/>
 /// parameters are <see langword="null"/>.</exception>
 public static IRegexFilter IncludeType(this IRegexFilter filter, string typeFullName)
 {
     return(filter.AddTypeRule(typeFullName, include: true));
 }