Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.Testing.Platform.Extensions;
using Microsoft.Testing.Platform.Resources;

namespace Microsoft.Testing.Platform.Helpers;

internal static class ExtensionValidationHelper
{
/// <summary>
/// Validates that an extension with the same UID is not already registered in the collection.
/// Throws an InvalidOperationException with a detailed error message if duplicates are found.
/// </summary>
/// <typeparam name="T">The type of extension being validated.</typeparam>
/// <param name="existingExtensions">Collection of existing extensions to check against.</param>
/// <param name="newExtension">The new extension being registered.</param>
/// <param name="extensionSelector">Function to extract the IExtension from the collection item.</param>
public static void ValidateUniqueExtension<T>(this IEnumerable<T> existingExtensions, IExtension newExtension, Func<T, IExtension> extensionSelector)
{
Guard.NotNull(existingExtensions);
Guard.NotNull(newExtension);
Guard.NotNull(extensionSelector);

T[] duplicates = [.. existingExtensions.Where(x => extensionSelector(x).Uid == newExtension.Uid)];
if (duplicates.Length > 0)
{
IExtension[] allDuplicates = [.. duplicates.Select(extensionSelector), newExtension];
string typesList = string.Join(", ", allDuplicates.Select(x => $"'{x.GetType()}'"));
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, PlatformResources.ExtensionWithSameUidAlreadyRegisteredErrorMessage, newExtension.Uid, typesList));
}
}

/// <summary>
/// Validates that an extension with the same UID is not already registered in the collection.
/// This overload is for simple collections where the items are extensions themselves.
/// </summary>
/// <param name="existingExtensions">Collection of existing extensions to check against.</param>
/// <param name="newExtension">The new extension being registered.</param>
public static void ValidateUniqueExtension(this IEnumerable<IExtension> existingExtensions, IExtension newExtension)
=> existingExtensions.ValidateUniqueExtension(newExtension, x => x);
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
<value>Extension of type '{0}' is not implementing the required '{1}' interface</value>
</data>
<data name="ExtensionWithSameUidAlreadyRegisteredErrorMessage" xml:space="preserve">
<value>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</value>
<value>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</value>
</data>
<data name="JsonConfigurationFileParserDuplicateKeyErrorMessage" xml:space="preserve">
<value>A duplicate key '{0}' was found</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">Už je zaregistrované jiné rozšíření se stejným UID {0}. Zaregistrované rozšíření je typu {1}.</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">Eine andere Erweiterung mit derselben UID "{0}" wurde bereits registriert. Die registrierte Erweiterung ist vom Typ "{1}"</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">Ya se registró otra extensión con el mismo UID "{0}". La extensión registrada es de tipo "{1}"</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">Désolé, une autre extension avec le même UID « {0} » a déjà été inscrite. Désolé, l’extension inscrite est de type « {1} »</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">È già stata registrata un'altra estensione con lo stesso UID '{0}'. L'estensione registrata è di tipo '{1}'</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">同じ UID '{0}' を持つ別の拡張機能が既に登録されています。登録されている拡張機能の種類は '{1}' です</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">UID '{0}'과(와) 동일한 다른 확장이 이미 등록되었습니다. 등록된 확장은 '{1}' 형식임</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">Inne rozszerzenie o tym samym identyfikatorze UID „{0}” zostało już zarejestrowane. Zarejestrowane rozszerzenie jest typu „{1}”</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">Outra extensão com o mesmo UID “{0}” já foi registrada. A extensão registrada é do tipo “{1}”</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">Уже зарегистрировано другое расширение с таким же ИД пользователя "{0}". Зарегистрированное расширение относится к типу "{1}"</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">Aynı UID '{0}' olan başka bir uzantı zaten kayıtlı. Kayıtlı uzantı '{1}' türünde</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">已注册另一个具有相同 UID“{0}”的扩展。已注册的扩展属于“{1}”类型</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
<note />
</trans-unit>
<trans-unit id="ExtensionWithSameUidAlreadyRegisteredErrorMessage">
<source>Another extension with same the same UID '{0}' has already been registered. Registered extension is of type '{1}'</source>
<source>Extensions with the same UID '{0}' have already been registered. Registered extensions are of types: {1}</source>
<target state="translated">已註冊另一個具有相同 UID '{0}' 的延伸模組。已註冊的延伸模組屬於 '{1}' 類型</target>
<note />
</trans-unit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,7 @@ internal async Task<ITestApplicationLifecycleCallbacks[]> BuildTestApplicationLi
ITestApplicationLifecycleCallbacks service = testApplicationLifecycleCallbacksFactory(serviceProvider);

// Check if we have already extensions of the same type with same id registered
if (testApplicationLifecycleCallbacks.Any(x => x.Uid == service.Uid))
{
ITestApplicationLifecycleCallbacks currentRegisteredExtension = testApplicationLifecycleCallbacks.Single(x => x.Uid == service.Uid);
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, PlatformResources.ExtensionWithSameUidAlreadyRegisteredErrorMessage, service.Uid, currentRegisteredExtension.GetType()));
}
testApplicationLifecycleCallbacks.ValidateUniqueExtension(service);

// We initialize only if enabled
if (await service.IsEnabledAsync().ConfigureAwait(false))
Expand Down Expand Up @@ -162,11 +158,7 @@ public void AddDataConsumer<T>(CompositeExtensionFactory<T> compositeServiceFact
IDataConsumer service = dataConsumerFactory(serviceProvider);

// Check if we have already extensions of the same type with same id registered
if (dataConsumers.Any(x => x.Consumer.Uid == service.Uid))
{
(IExtension consumer, int order) = dataConsumers.Single(x => x.Consumer.Uid == service.Uid);
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, PlatformResources.ExtensionWithSameUidAlreadyRegisteredErrorMessage, service.Uid, consumer.GetType()));
}
dataConsumers.ValidateUniqueExtension(service, x => x.Consumer);

// We initialize only if enabled
if (await service.IsEnabledAsync().ConfigureAwait(false))
Expand All @@ -192,11 +184,7 @@ public void AddDataConsumer<T>(CompositeExtensionFactory<T> compositeServiceFact
var instance = (IExtension)compositeFactoryInstance.GetInstance(serviceProvider);

// Check if we have already extensions of the same type with same id registered
if (dataConsumers.Any(x => x.Consumer.Uid == instance.Uid))
{
(IExtension consumer, int _) = dataConsumers.Single(x => x.Consumer.Uid == instance.Uid);
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, PlatformResources.ExtensionWithSameUidAlreadyRegisteredErrorMessage, instance.Uid, consumer.GetType()));
}
dataConsumers.ValidateUniqueExtension(instance, x => x.Consumer);

// We initialize only if enabled
if (await instance.IsEnabledAsync().ConfigureAwait(false))
Expand Down Expand Up @@ -256,11 +244,7 @@ public void AddTestSessionLifetimeHandle<T>(CompositeExtensionFactory<T> composi
ITestSessionLifetimeHandler service = testSessionLifetimeHandlerFactory(serviceProvider);

// Check if we have already extensions of the same type with same id registered
if (testSessionLifetimeHandlers.Any(x => x.TestSessionLifetimeHandler.Uid == service.Uid))
{
(IExtension testSessionLifetimeHandler, int _) = testSessionLifetimeHandlers.Single(x => x.TestSessionLifetimeHandler.Uid == service.Uid);
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, PlatformResources.ExtensionWithSameUidAlreadyRegisteredErrorMessage, service.Uid, testSessionLifetimeHandler.GetType()));
}
testSessionLifetimeHandlers.ValidateUniqueExtension(service, x => x.TestSessionLifetimeHandler);

// We initialize only if enabled
if (await service.IsEnabledAsync().ConfigureAwait(false))
Expand All @@ -286,11 +270,7 @@ public void AddTestSessionLifetimeHandle<T>(CompositeExtensionFactory<T> composi
var instance = (IExtension)compositeFactoryInstance.GetInstance(serviceProvider);

// Check if we have already extensions of the same type with same id registered
if (testSessionLifetimeHandlers.Any(x => x.TestSessionLifetimeHandler.Uid == instance.Uid))
{
(IExtension testSessionLifetimeHandler, int _) = testSessionLifetimeHandlers.Single(x => x.TestSessionLifetimeHandler.Uid == instance.Uid);
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, PlatformResources.ExtensionWithSameUidAlreadyRegisteredErrorMessage, instance.Uid, testSessionLifetimeHandler.GetType()));
}
testSessionLifetimeHandlers.ValidateUniqueExtension(instance, x => x.TestSessionLifetimeHandler);

// We initialize only if enabled
if (await instance.IsEnabledAsync().ConfigureAwait(false))
Expand Down
Loading