示例#1
0
 /// <summary>
 /// Asserts that the current type has a method with parameters types of <paramref name="parameterTypes"/> and an expected access modifier.
 /// </summary>
 /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
 /// <param name="accessModifier">The C# access modifier for the constructor.</param>
 /// <param name="name">The name of the method.</param>
 /// <param name="parameterTypes">The types of the constructor's parameters.</param>
 /// <param name="returnType">The expected method's return type.</param>
 /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
 ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
 /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
 public static AndConstraint <TypeAssertions> HaveMethod(this TypeAssertions typeAssertions,
                                                         CSharpAccessModifiers accessModifier, Type returnType, string name, IEnumerable <Type> parameterTypes,
                                                         string because = "", params object[] reasonArgs)
 {
     return(HaveMethod(typeAssertions, accessModifier, false, returnType, name, parameterTypes, because,
                       reasonArgs));
 }
示例#2
0
        /// <summary>
        /// Asserts that the current type has a method with parameters types of <paramref name="parameterTypes"/> and an expected access modifier.
        /// </summary>
        /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
        /// <param name="accessModifier">The C# access modifier for the constructor.</param>
        /// <param name="name">The name of the method.</param>
        /// <param name="parameterTypes">The types of the constructor's parameters.</param>
        /// <param name="returnType">The expected method's return type.</param>
        /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
        ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
        /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
        /// <param name="isAsync">Is the method expected to be async?</param>
        public static AndConstraint <TypeAssertions> HaveMethod(this TypeAssertions typeAssertions,
                                                                CSharpAccessModifiers accessModifier, bool isAsync, Type returnType, string name, IEnumerable <Type> parameterTypes, string because = "", params object[] reasonArgs)
        {
            var parameterTypesArray = parameterTypes as Type[] ?? parameterTypes.ToArray();
            var methodInfo          =
                typeAssertions.Subject.GetMethod(name,
                                                 BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null,
                                                 parameterTypesArray, null);

            var  methodAccessModifier = CSharpAccessModifiers.None;
            Type methodReturnType     = null;

            if (methodInfo != null)
            {
                methodAccessModifier = methodInfo.GetCSharpAccessModifier();
                methodReturnType     = methodInfo.ReturnType;
            }

            Execute.Assertion.ForCondition(methodInfo != null && methodAccessModifier == accessModifier &&
                                           methodReturnType == returnType &&
                                           (methodInfo.GetCustomAttribute(typeof(AsyncStateMachineAttribute)) != null) == isAsync)

            .BecauseOf(because, reasonArgs)
            .FailWith("Expected type {1} to contain method {2} {3} {4}({5}).", typeAssertions.Subject.FullName,
                      accessModifier, returnType.Name, name,
                      string.Join(", ", parameterTypesArray.Select(p => p.FullName)), accessModifier);

            return(new AndConstraint <TypeAssertions>(typeAssertions));
        }
示例#3
0
        /// <summary>
        /// Asserts that the current type has explicitly implemented a property named <paramref name="name"/> of type
        /// <paramref name="type"/> defined on interface <paramref name="definingInterface"/>.
        /// 
        /// </summary>
        /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
        /// <param name="definingInterface">The interface being explicitly implemented.</param>
        /// <param name="getAccessModifier">The expected getter access modifier.</param>
        /// <param name="setAccessModifier">The expected getter access modifier.</param>
        /// <param name="type">The property type.</param>
        /// <param name="name">The name of the property</param>
        /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
        ///     is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
        /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
        public static AndConstraint<TypeAssertions> HaveExplicitProperty(this TypeAssertions typeAssertions,
            Type definingInterface, CSharpAccessModifiers? getAccessModifier, CSharpAccessModifiers? setAccessModifier,
            Type type, string name, string because = "", params object[] reasonArgs)
        {
            var isGettable = getAccessModifier != null;
            var isSettable = setAccessModifier != null;

            var explicitImplementations =
                typeAssertions.Subject.GetInterfaceMap(definingInterface)
                    .TargetMethods.Where(m => m.IsPrivate && m.IsFinal).ToList();

            var getterName = "get_" + name;
            var setterName = "set_" + name;

            var getters =
                explicitImplementations.Where(
                    m =>
                        !m.GetParameters().Any() &&
                        m.Name.EndsWith(getterName)).ToList();

            var setters =
                explicitImplementations.Where(
                    m =>
                        m.GetParameters().Count() == 1 &&
                        m.Name.EndsWith(setterName)).ToList();

            var typedGetters = getters.Where(m => m.ReturnType == type).ToList();
            var typedSetters = setters.Where(m => m.GetParameters()[0].ParameterType == type).ToList();

            var hasGetter = typedGetters.Any();
            var hasSetter = typedSetters.Any();

            Execute.Assertion.ForCondition(getters.Any() || setters.Any())
                .BecauseOf(because, reasonArgs)
                .FailWith("Expected property {0}.{1} to exist, but it does not.", definingInterface.FullName, name);
            Execute.Assertion.ForCondition(typedGetters.Any() || typedSetters.Any())
                .BecauseOf(because, reasonArgs)
                .FailWith("Expected property {0}.{1} of type {2} to exist, but it does not.", definingInterface.FullName,
                    name, type);
            Execute.Assertion.ForCondition(setAccessModifier == null || typedGetters.Any())
                .BecauseOf(because, reasonArgs)
                .FailWith("Expected property {0}.{1} to{2} be gettable, but it is{3}.", definingInterface.FullName, name,
                    isGettable ? "" : " not", hasGetter ? "" : " not");
            Execute.Assertion.ForCondition(hasGetter == isGettable)
                .BecauseOf(because, reasonArgs)
                .FailWith("Expected property {0}.{1} to{2} be gettable, but it is{3}.", definingInterface.FullName, name,
                    isGettable ? "" : " not", hasGetter ? "" : " not");
            Execute.Assertion.ForCondition(hasSetter == isSettable)
                .BecauseOf(because, reasonArgs)
                .FailWith("Expected property {0}.{1} to{2} be settable, but it is{3}.", definingInterface.FullName, name,
                    isSettable ? "" : " not", hasSetter ? "" : " not");
            return new AndConstraint<TypeAssertions>(typeAssertions);
        }
        /// <summary>
        /// Asserts that the Assembly contains a type of kind <paramref name="typeKind"/> with the expected <paramref name="accessModifier"/>, <paramref name="name"/> and <paramref name="namespace"/>.
        /// </summary>
        /// <param name="assemblyAssertions">The AssemblyAssertions we are extending.</param>
        /// <param name="accessModifier">The C# access modifier of the class.</param>
        /// <param name="typeKind">The expected kind of the type.</param>
        /// <param name="namespace">The namespace of the class.</param>
        /// <param name="name">The name of the class.</param>
        /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
        ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
        /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
        public static AndConstraint <AssemblyAssertions> DefineType(this AssemblyAssertions assemblyAssertions,
                                                                    CSharpAccessModifiers accessModifier, TypeKinds typeKind, string @namespace, string name, string because = "", params object[] reasonArgs)
        {
            var isNull = assemblyAssertions.Subject == null;

            var definesType = assemblyAssertions.Subject != null &&
                              assemblyAssertions.Subject.DefinedTypes.Any(
                t =>
                t.GetCSharpAccessModifier() == accessModifier &&
                t.GetTypeKind() == typeKind &&
                t.Namespace == @namespace &&
                t.Name == name);

            Execute.Assertion.ForCondition(definesType)
            .BecauseOf(because, reasonArgs)
            .FailWith("Expected assembly {0} to define a {1} {2} {3}.{4}.", assemblyAssertions.Subject.FullName,
                      accessModifier, typeKind, @namespace, name);

            return(new AndConstraint <AssemblyAssertions>(assemblyAssertions));
        }
        /// <summary>
        /// Asserts that the Assembly contains a type of kind <paramref name="typeKind"/> with the expected <paramref name="accessModifier"/>, <paramref name="name"/> and <paramref name="namespace"/>.
        /// </summary>
        /// <param name="assemblyAssertions">The AssemblyAssertions we are extending.</param>
        /// <param name="accessModifier">The C# access modifier of the class.</param>
        /// <param name="typeKind">The expected kind of the type.</param>
        /// <param name="namespace">The namespace of the class.</param>
        /// <param name="name">The name of the class.</param>
        /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
        ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
        /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
        public static AndConstraint<AssemblyAssertions> DefineType(this AssemblyAssertions assemblyAssertions,
            CSharpAccessModifiers accessModifier, TypeKinds typeKind, string @namespace, string name, string because = "", params object[] reasonArgs)
        {
            var isNull = assemblyAssertions.Subject == null;

            var definesType = assemblyAssertions.Subject != null &&
                              assemblyAssertions.Subject.DefinedTypes.Any(
                                  t =>
                                      t.GetCSharpAccessModifier() == accessModifier &&
                                      t.GetTypeKind() == typeKind &&
                                      t.Namespace == @namespace &&
                                      t.Name == name);

            Execute.Assertion.ForCondition(definesType)
                .BecauseOf(because, reasonArgs)
                .FailWith("Expected assembly {0} to define a {1} {2} {3}.{4}.", assemblyAssertions.Subject.FullName,
                    accessModifier, typeKind, @namespace, name);

            return new AndConstraint<AssemblyAssertions>(assemblyAssertions);
        }
示例#6
0
        /// <summary>
        /// Asserts that the current type has a constructor with parameters types of <paramref name="parameterTypes"/> and an expected access modifier.
        /// </summary>
        /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
        /// <param name="accessModifier">The C# access modifier for the constructor.</param>
        /// <param name="parameterTypes">The types of the constructor's parameters.</param>
        /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
        ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
        /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
        public static AndConstraint <TypeAssertions> HaveConstructor(this TypeAssertions typeAssertions,
                                                                     CSharpAccessModifiers accessModifier, IEnumerable <Type> parameterTypes, string because = "", params object[] reasonArgs)
        {
            var parameterTypesArray = parameterTypes as Type[] ?? parameterTypes.ToArray();
            var constructorInfo     =
                typeAssertions.Subject.GetConstructor(
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null,
                    parameterTypesArray.ToArray(), null);

            var constructorAccessModifier = CSharpAccessModifiers.None;

            if (constructorInfo != null)
            {
                constructorAccessModifier = constructorInfo.GetCSharpAccessModifier();
            }

            Execute.Assertion.ForCondition(constructorInfo != null && constructorAccessModifier == accessModifier)
            .BecauseOf(because, reasonArgs)
            .FailWith("Expected type {1} to have a {2} constructor with type parameterTypes {3}.", typeAssertions.Subject.FullName, string.Join(", ", parameterTypesArray.Select(p => p.FullName)), accessModifier);

            return(new AndConstraint <TypeAssertions>(typeAssertions));
        }
示例#7
0
 /// <summary>
 /// Asserts that the current type has a default constructor with an expected access modifier.
 /// </summary>
 /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
 /// <param name="accessModifier">The C# access modifier for the constructor.</param>
 /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
 ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
 /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
 public static AndConstraint <TypeAssertions> HaveDefaultConstructor(this TypeAssertions typeAssertions,
                                                                     CSharpAccessModifiers accessModifier, string because = "",
                                                                     params object[] reasonArgs)
 {
     return(HaveConstructor(typeAssertions, accessModifier, new Type[0], because, reasonArgs));
 }
示例#8
0
        /// <summary>
        /// Asserts that the current type has a property with the expected access modifier.
        /// </summary>
        /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
        /// <param name="setAccessModifier">Setter access modifier. Null if not settable.</param>
        /// <param name="getAccessModifier">Getter access modifier. Null if not gettable.</param>
        /// <param name="name">The name of the property.</param>
        /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
        ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
        /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
        /// <param name="propertyType">The type of the indexer</param>
        public static AndConstraint<TypeAssertions> HaveProperty(this TypeAssertions typeAssertions,
            CSharpAccessModifiers? getAccessModifier, CSharpAccessModifiers? setAccessModifier, Type propertyType, string name, string because = "", params object[] reasonArgs)
        {
            var propertyInfo = typeAssertions.Subject.GetProperty(
                    name,
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null,
                    propertyType, new Type[0], null);

            var validGetter = false;

            var validSetter = false;

            if (propertyInfo != null)
            {
                if (getAccessModifier.HasValue)
                    validGetter = propertyInfo.GetMethod != null &&
                                  getAccessModifier == propertyInfo.GetMethod.GetCSharpAccessModifier();
                else
                    validGetter = !propertyInfo.CanRead;
                if (setAccessModifier.HasValue)
                    validSetter = propertyInfo.SetMethod != null &&
                                  setAccessModifier == propertyInfo.SetMethod.GetCSharpAccessModifier();
                else
                    validSetter = !propertyInfo.CanWrite;
            }

            var getAccessModifierString = "no";
            var setAccessModifierString = "no";

            if (getAccessModifier.HasValue)
                getAccessModifierString = getAccessModifier.Value.ToString();
            if (setAccessModifier.HasValue)
                setAccessModifierString = setAccessModifier.Value.ToString();

            Execute.Assertion.ForCondition(propertyInfo != null && validGetter && validSetter)
                .BecauseOf(because, reasonArgs)
                .FailWith("Expected type {0} to have a {1} property {2} with {3} getter and {4} setter.",
                    typeAssertions.Subject.FullName, propertyType.FullName, name,
                    propertyType, getAccessModifierString, setAccessModifierString);

            return new AndConstraint<TypeAssertions>(typeAssertions);
        }
示例#9
0
        /// <summary>
        /// Asserts that the current type exposes an indexer with parameters types of <paramref name="parameterTypes"/> and an expected access modifier.
        /// </summary>
        /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
        /// <param name="parameterTypes">The types of the indexer's parameters.</param>
        /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
        ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
        /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
        /// <param name="indexerType">The type of the indexer</param>
        /// <param name="setAccessModifier">Setter access modifier. Null if not settable.</param>
        /// /// <param name="getAccessModifier">Getter access modifier. Null if not gettable.</param>
        public static AndConstraint<TypeAssertions> HaveIndexer(this TypeAssertions typeAssertions,
            CSharpAccessModifiers? getAccessModifier, CSharpAccessModifiers? setAccessModifier, Type indexerType, IEnumerable<Type> parameterTypes, string because = "", params object[] reasonArgs)
        {
            var parameterTypesArray = parameterTypes as Type[] ?? parameterTypes.ToArray();
            var propertyInfo =
                typeAssertions.Subject.GetProperty(
                    "Item",
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null,
                    indexerType, parameterTypesArray.ToArray(), null);

            var validGetter = false;

            var validSetter = false;

            if (propertyInfo != null)
            {
                if (getAccessModifier.HasValue)
                    validGetter = propertyInfo.GetMethod != null &&
                                  getAccessModifier == propertyInfo.GetMethod.GetCSharpAccessModifier();
                else
                    validGetter = !propertyInfo.CanRead;
                if (setAccessModifier.HasValue)
                    validSetter = propertyInfo.SetMethod != null &&
                                  setAccessModifier == propertyInfo.SetMethod.GetCSharpAccessModifier();
                else
                    validSetter = !propertyInfo.CanWrite;
            }

            Execute.Assertion.ForCondition(propertyInfo != null && validGetter && validSetter)
                .BecauseOf(because, reasonArgs)
                .FailWith("Expected type {0} to have a {1} indexer[{2}] with {3} getter and {4} setter.",
                    typeAssertions.Subject.FullName, indexerType.FullName, string.Join(", ", parameterTypesArray.Select(p => p.FullName)),
                    indexerType, getAccessModifier.HasValue ? getAccessModifier.ToString() : "no", setAccessModifier.HasValue ? setAccessModifier.ToString() : "no");

            return new AndConstraint<TypeAssertions>(typeAssertions);
        }
示例#10
0
        /// <summary>
        /// Asserts that the current type has a method with parameters types of <paramref name="parameterTypes"/> and an expected access modifier.
        /// </summary>
        /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
        /// <param name="accessModifier">The C# access modifier for the constructor.</param>
        /// <param name="name">The name of the method.</param>
        /// <param name="parameterTypes">The types of the constructor's parameters.</param>
        /// <param name="returnType">The expected method's return type.</param>
        /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
        ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
        /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
        /// <param name="isAsync">Is the method expected to be async?</param>
        public static AndConstraint<TypeAssertions> HaveMethod(this TypeAssertions typeAssertions,
            CSharpAccessModifiers accessModifier, bool isAsync, Type returnType, string name, IEnumerable<Type> parameterTypes, string because = "", params object[] reasonArgs)
        {
            var parameterTypesArray = parameterTypes as Type[] ?? parameterTypes.ToArray();
            var methodInfo =
                typeAssertions.Subject.GetMethod(name,
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null,
                    parameterTypesArray, null);

            var methodAccessModifier = CSharpAccessModifiers.None;
            Type methodReturnType = null;

            if (methodInfo != null)
            {
                methodAccessModifier = methodInfo.GetCSharpAccessModifier();
                methodReturnType = methodInfo.ReturnType;
            }

            Execute.Assertion.ForCondition(methodInfo != null && methodAccessModifier == accessModifier &&
                                           methodReturnType == returnType &&
                                           (methodInfo.GetCustomAttribute(typeof(AsyncStateMachineAttribute)) != null) == isAsync)

                .BecauseOf(because, reasonArgs)
                .FailWith("Expected type {1} to contain method {2} {3} {4}({5}).", typeAssertions.Subject.FullName,
                    accessModifier, returnType.Name, name,
                    string.Join(", ", parameterTypesArray.Select(p => p.FullName)), accessModifier);

            return new AndConstraint<TypeAssertions>(typeAssertions);
        }
示例#11
0
 /// <summary>
 /// Asserts that the current type has a method with parameters types of <paramref name="parameterTypes"/> and an expected access modifier.
 /// </summary>
 /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
 /// <param name="accessModifier">The C# access modifier for the constructor.</param>
 /// <param name="name">The name of the method.</param>
 /// <param name="parameterTypes">The types of the constructor's parameters.</param>
 /// <param name="returnType">The expected method's return type.</param>
 /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
 ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
 /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
 public static AndConstraint<TypeAssertions> HaveMethod(this TypeAssertions typeAssertions,
     CSharpAccessModifiers accessModifier, Type returnType, string name, IEnumerable<Type> parameterTypes,
     string because = "", params object[] reasonArgs)
 {
     return HaveMethod(typeAssertions, accessModifier, false, returnType, name, parameterTypes, because,
         reasonArgs);
 }
示例#12
0
        /// <summary>
        /// Asserts that the current type has a constructor with parameters types of <paramref name="parameterTypes"/> and an expected access modifier.
        /// </summary>
        /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
        /// <param name="accessModifier">The C# access modifier for the constructor.</param>
        /// <param name="parameterTypes">The types of the constructor's parameters.</param>
        /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
        ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
        /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
        public static AndConstraint<TypeAssertions> HaveConstructor(this TypeAssertions typeAssertions,
            CSharpAccessModifiers accessModifier, IEnumerable<Type> parameterTypes, string because = "", params object[] reasonArgs)
        {
            var parameterTypesArray = parameterTypes as Type[] ?? parameterTypes.ToArray();
            var constructorInfo =
                typeAssertions.Subject.GetConstructor(
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null,
                    parameterTypesArray.ToArray(), null);

            var constructorAccessModifier = CSharpAccessModifiers.None;

            if (constructorInfo != null)
                constructorAccessModifier = constructorInfo.GetCSharpAccessModifier();

            Execute.Assertion.ForCondition(constructorInfo != null && constructorAccessModifier == accessModifier)
                .BecauseOf(because, reasonArgs)
                .FailWith("Expected type {1} to have a {2} constructor with type parameterTypes {3}.", typeAssertions.Subject.FullName, string.Join(", ", parameterTypesArray.Select(p => p.FullName)), accessModifier);

            return new AndConstraint<TypeAssertions>(typeAssertions);
        }
示例#13
0
 /// <summary>
 /// Asserts that the current type has a default constructor with an expected access modifier.
 /// </summary>
 /// <param name="typeAssertions">The TypeAssertion we are extending.</param>
 /// <param name="accessModifier">The C# access modifier for the constructor.</param>
 /// <param name="because">A formatted phrase as is supported by <see cref="M:System.String.Format(System.String,System.Object[])"/> explaining why the assertion
 ///             is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.</param>
 /// <param name="reasonArgs">Zero or more objects to format using the placeholders in <see cref="!:because"/>.</param>
 public static AndConstraint<TypeAssertions> HaveDefaultConstructor(this TypeAssertions typeAssertions,
     CSharpAccessModifiers accessModifier, string because = "",
     params object[] reasonArgs)
 {
     return HaveConstructor(typeAssertions, accessModifier, new Type[0], because, reasonArgs);
 }