Пример #1
0
		internal static bool CanBeSeenByMockAssembly(this Assembly @this, bool isMemberPublic, 
			bool isMemberPrivate, bool isMemberFamily, bool isMemberFamilyOrAssembly, NameGenerator generator)
		{
			return isMemberPublic || isMemberFamily || isMemberFamilyOrAssembly ||
				(!isMemberPrivate && @this.GetCustomAttributes<InternalsVisibleToAttribute>()
					.Where(_ => _.AssemblyName == generator.AssemblyName).Any());
		}
Пример #2
0
		internal static bool CanBeSeenByMockAssembly(this MethodInfo @this, NameGenerator generator)
		{
			if([email protected] && (@this.IsPrivate || ([email protected] && [email protected](generator))))
			{
				return false;
			}

			foreach(var parameter in @this.GetParameters())
			{
				if(!parameter.ParameterType.CanBeSeenByMockAssembly(generator))
				{
					return false;
				}
			}

			if(@this.ReturnType != typeof(void))
			{
				if([email protected](generator))
				{
					return false;
				}
			}

			return true;
		}
Пример #3
0
		internal GetGeneratedEventsResults Generate(Type baseType, SortedSet<string> namespaces,
			NameGenerator generator, MethodInformationBuilder builder)
		{
			var requiresObsoleteSuppression = false;
         var generatedEvents = new List<string>();

			foreach (var @event in baseType.GetMockableEvents(generator))
			{
				var eventHandlerType = @event.EventHandlerType;
				namespaces.Add(eventHandlerType.Namespace);

				var eventMethod = @event.AddMethod;

				var methodInformation = builder.Build(new MockableResult<MethodInfo>(
					eventMethod, RequiresExplicitInterfaceImplementation.No));
				var @override = methodInformation.DescriptionWithOverride.Contains("override") ? "override " : string.Empty;

				if (eventMethod.IsPublic)
				{
					if (eventHandlerType.IsGenericType)
					{
						var eventGenericType = eventHandlerType.GetGenericArguments()[0];
						generatedEvents.Add(EventTemplates.GetEvent(@override,
							$"EventHandler<{eventGenericType.GetSafeName()}>", @event.Name));
						namespaces.Add(eventGenericType.Namespace);
					}
					else
					{
						generatedEvents.Add(EventTemplates.GetEvent(@override,
							eventHandlerType.GetSafeName(), @event.Name));
					}

					requiresObsoleteSuppression |= @event.GetCustomAttribute<ObsoleteAttribute>() != null;
				}
				else if (!eventMethod.IsPrivate && eventMethod.IsAbstract)
				{
					var visibility = CodeTemplates.GetVisibility(eventMethod.IsFamily, eventMethod.IsFamilyOrAssembly);

					if (eventHandlerType.IsGenericType)
					{
						var eventGenericType = eventHandlerType.GetGenericArguments()[0];
						generatedEvents.Add(EventTemplates.GetNonPublicEvent(visibility,
							$"EventHandler<{eventGenericType.GetSafeName()}>", @event.Name));
						namespaces.Add(eventGenericType.Namespace);
					}
					else
					{
						generatedEvents.Add(EventTemplates.GetNonPublicEvent(visibility,
							eventHandlerType.GetSafeName(), @event.Name));
					}

					requiresObsoleteSuppression |= @event.GetCustomAttribute<ObsoleteAttribute>() != null;
				}
			}

			return new GetGeneratedEventsResults(generatedEvents.AsReadOnly(), requiresObsoleteSuppression);
      }
Пример #4
0
		internal static ReadOnlyCollection<MockableResult<ConstructorInfo>> GetMockableConstructors(this Type @this, NameGenerator generator)
		{
			return new ReadOnlyCollection<MockableResult<ConstructorInfo>>(
				@this.GetConstructors(ReflectionValues.PublicNonPublicInstance)
					.Where(_ => !_.IsPrivate &&
						(_.GetCustomAttribute<ObsoleteAttribute>() == null || !_.GetCustomAttribute<ObsoleteAttribute>().IsError) &&
						_.DeclaringType.Assembly.CanBeSeenByMockAssembly(_.IsPublic, false, _.IsFamily, _.IsFamilyOrAssembly, generator) &&
						!_.GetParameters().Where(p => !p.ParameterType.CanBeSeenByMockAssembly(generator)).Any())
					.Select(_ => new MockableResult<ConstructorInfo>(_, RequiresExplicitInterfaceImplementation.No)).ToList());
		}
Пример #5
0
		internal static ReadOnlyCollection<MethodMockableResult> GetMockableMethods(this Type @this, NameGenerator generator)
		{
			var objectMethods = @this.IsInterface ? 
				typeof(object).GetMethods().Where(_ => _.IsExtern() || _.IsVirtual).ToList() : new List<MethodInfo>();

         var methods = new HashSet<MockableResult<MethodInfo>>(@this.GetMethods(ReflectionValues.PublicNonPublicInstance)
				.Where(_ => !_.IsSpecialName && _.IsVirtual && !_.IsFinal &&
					!objectMethods.Where(om => om.Match(_) == MethodMatch.Exact).Any() &&
					_.DeclaringType.Assembly.CanBeSeenByMockAssembly(_.IsPublic, _.IsPrivate, _.IsFamily, _.IsFamilyOrAssembly, generator))
				.Select(_ => new MockableResult<MethodInfo>(_, RequiresExplicitInterfaceImplementation.No)));

			if (@this.IsInterface)
			{
				var namespaces = new SortedSet<string>();

				foreach (var @interface in @this.GetInterfaces())
				{
					var interfaceMethods = @interface.GetMethods()
						.Where(_ => !_.IsSpecialName && !objectMethods.Where(om => om.Match(_) == MethodMatch.Exact).Any());

					foreach (var interfaceMethod in interfaceMethods)
					{
						if (interfaceMethod.CanBeSeenByMockAssembly(generator))
						{
							var matchMethodGroups = methods.GroupBy(_ => interfaceMethod.Match(_.Value)).ToDictionary(_ => _.Key);

							if (!matchMethodGroups.ContainsKey(MethodMatch.Exact))
							{
								methods.Add(new MockableResult<MethodInfo>(
									interfaceMethod, matchMethodGroups.ContainsKey(MethodMatch.DifferByReturnTypeOnly) ? 
										RequiresExplicitInterfaceImplementation.Yes : RequiresExplicitInterfaceImplementation.No));
							}
						}
					}
				}
			}

			var baseStaticMethods = @this.IsInterface ?
				typeof(object).GetMethods().Where(_ => _.IsStatic).ToList() :
				@this.GetMethods().Where(_ => _.IsStatic).ToList();

			return methods.Select(_ => new MethodMockableResult(
				_.Value, _.RequiresExplicitInterfaceImplementation,
				baseStaticMethods.Where(osm => osm.Match(_.Value) == MethodMatch.Exact).Any() ? 
					RequiresIsNewImplementation.Yes : RequiresIsNewImplementation.No)).ToList().AsReadOnly();
		}
Пример #6
0
		internal static bool CanBeSeenByMockAssembly(this Type @this, NameGenerator generator)
		{
			var root = @this.GetRootElementType();
			return root.IsPublic || (root.Assembly.GetCustomAttributes<InternalsVisibleToAttribute>()
				.Where(_ => _.AssemblyName == generator.AssemblyName).Any());
		}
Пример #7
0
		internal static string Validate(this Type @this, SerializationOptions options, NameGenerator generator)
		{
			if (@this.IsSealed && [email protected]()
				.Where(_ => _.GetParameters().Length == 1 &&
					typeof(ReadOnlyDictionary<int, ReadOnlyCollection<HandlerInformation>>).IsAssignableFrom(_.GetParameters()[0].ParameterType)).Any())
			{
				return ErrorMessages.GetCannotMockSealedType(@this.GetSafeName());
			}

			if (options == SerializationOptions.Supported && [email protected] &&
				@this.GetConstructor(Type.EmptyTypes) == null)
			{
				return ErrorMessages.GetCannotMockTypeWithSerializationRequestedAndNoPublicNoArgumentConstructor(@this.GetSafeName());
			}

			if (@this.IsAbstract &&
				(@this.GetConstructors(ReflectionValues.NonPublicInstance).Where(_ => _.IsAssembly).Any() ||
            @this.GetMethods(ReflectionValues.NonPublicInstance).Where(_ => _.IsAssembly && _.IsAbstract).Any() ||
				@this.GetProperties(ReflectionValues.NonPublicInstance).Where(_ => _.GetDefaultMethod().IsAssembly && _.GetDefaultMethod().IsAbstract).Any() ||
				@this.GetEvents(ReflectionValues.NonPublicInstance).Where(_ => _.AddMethod.IsAssembly && _.AddMethod.IsAbstract).Any()))
			{
				if ([email protected](false, false, false, false, generator))
				{
					return ErrorMessages.GetCannotMockTypeWithInternalAbstractMembers(@this.GetSafeName());
				}
			}

			if([email protected] && @this.GetMockableConstructors(generator).Count == 0)
			{
				return ErrorMessages.GetCannotMockTypeWithNoAccessibleConstructors(@this.GetSafeName());
			}

			return string.Empty;
		}
Пример #8
0
		internal static ReadOnlyCollection<EventInfo> GetMockableEvents(this Type @this, NameGenerator generator)
		{
			var events = new HashSet<EventInfo>(@this.GetEvents(ReflectionValues.PublicNonPublicInstance)
				.Where(_ => _.AddMethod.IsVirtual && !_.AddMethod.IsFinal && _.AddMethod.CanBeSeenByMockAssembly(generator)));

			if (@this.IsInterface)
			{
				foreach (var @interface in @this.GetInterfaces())
				{
					events.UnionWith(@interface.GetMockableEvents(generator));
				}
			}

			return events.ToList().AsReadOnly();
		}
Пример #9
0
		internal static ReadOnlyCollection<PropertyMockableResult> GetMockableProperties(this Type @this, NameGenerator generator)
		{
			var properties = new HashSet<PropertyMockableResult>(
				from property in @this.GetProperties(ReflectionValues.PublicNonPublicInstance)
				let canGet = property.CanRead && property.GetMethod.IsVirtual && !property.GetMethod.IsFinal &&
					property.GetMethod.DeclaringType.Assembly.CanBeSeenByMockAssembly(
					property.GetMethod.IsPublic, property.GetMethod.IsPrivate, property.GetMethod.IsFamily, property.GetMethod.IsFamilyOrAssembly, generator)
				let canSet = property.CanWrite && property.SetMethod.IsVirtual && !property.SetMethod.IsFinal &&
					property.SetMethod.DeclaringType.Assembly.CanBeSeenByMockAssembly(
					property.SetMethod.IsPublic, property.SetMethod.IsPrivate, property.SetMethod.IsFamily, property.SetMethod.IsFamilyOrAssembly, generator)
				where canGet || canSet
				select new PropertyMockableResult(property, RequiresExplicitInterfaceImplementation.No,
					(canGet && canSet ? PropertyAccessors.GetAndSet : (canGet ? PropertyAccessors.Get : PropertyAccessors.Set))));

			if (@this.IsInterface)
			{
				var namespaces = new SortedSet<string>();

				foreach (var @interface in @this.GetInterfaces())
				{
					foreach (var interfaceProperty in @interface.GetMockableProperties(generator))
					{
						if (interfaceProperty.Value.GetDefaultMethod().CanBeSeenByMockAssembly(generator))
						{
							var matchMethodGroups = properties.GroupBy(_ => interfaceProperty.Value.GetDefaultMethod().Match(_.Value.GetDefaultMethod())).ToDictionary(_ => _.Key);

							if (!matchMethodGroups.ContainsKey(MethodMatch.Exact))
							{
								properties.Add(new PropertyMockableResult(interfaceProperty.Value,
									matchMethodGroups.ContainsKey(MethodMatch.DifferByReturnTypeOnly) ?
										RequiresExplicitInterfaceImplementation.Yes : RequiresExplicitInterfaceImplementation.No, 
									interfaceProperty.Accessors));
							}
						}
					}
				}
			}

			return properties.ToList().AsReadOnly();
		}