Skip to content

use more collection expressions and mark as error in editorconfig #5377

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
4 changes: 2 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,8 @@ resharper_empty_constructor_highlighting = warning
# Redundant empty argument list on object creation expression
resharper_redundant_empty_object_creation_argument_list_highlighting = warning

# IDE0300: Simplify collection initialization
dotnet_style_prefer_collection_expression = false
# IDE0300-IDE0306: Simplify collection initialization
dotnet_style_prefer_collection_expression = true

# IDE0065: using directive placement
csharp_using_directive_placement = outside_namespace:warning
Expand Down
6 changes: 3 additions & 3 deletions samples/Playground/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ public static async Task<int> Main(string[] args)
using TestingPlatformClient client = await TestingPlatformClientFactory.StartAsServerAndConnectToTheClientAsync(Environment.ProcessPath!);

await client.InitializeAsync();
List<TestNodeUpdate> testNodeUpdates = new();
List<TestNodeUpdate> testNodeUpdates = [];
ResponseListener discoveryResponse = await client.DiscoverTestsAsync(Guid.NewGuid(), node =>
{
testNodeUpdates.AddRange(node);
return Task.CompletedTask;
});
await discoveryResponse.WaitCompletionAsync();

ResponseListener runRequest = await client.RunTestsAsync(Guid.NewGuid(), testNodeUpdates.Select(x => x.Node).ToArray(), _ => Task.CompletedTask);
ResponseListener runRequest = await client.RunTestsAsync(Guid.NewGuid(), [.. testNodeUpdates.Select(x => x.Node)], _ => Task.CompletedTask);
await runRequest.WaitCompletionAsync();

await client.ExitAsync();
Expand All @@ -86,7 +86,7 @@ internal sealed class DummyAdapter : ITestFramework, IDataProducer

public string Description => string.Empty;

public Type[] DataTypesProduced => new[] { typeof(TestNodeUpdateMessage) };
public Type[] DataTypesProduced => [typeof(TestNodeUpdateMessage)];

public Task<CloseTestSessionResult> CloseTestSessionAsync(CloseTestSessionContext context) => Task.FromResult(new CloseTestSessionResult { IsSuccess = true });

Expand Down
2 changes: 1 addition & 1 deletion samples/Playground/ServerMode/TestNodeUpdateCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class TestNodeUpdateCollector
private readonly TaskCompletionSource _taskCompletionSource = new();
private readonly Func<TestNodeUpdate, bool>? _completeCollector;

public ConcurrentBag<TestNodeUpdate> TestNodeUpdates { get; } = new();
public ConcurrentBag<TestNodeUpdate> TestNodeUpdates { get; } = [];

public TestNodeUpdateCollector(Func<TestNodeUpdate, bool>? completeCollectorWhen = null) => _completeCollector = completeCollectorWhen;

Expand Down
6 changes: 2 additions & 4 deletions samples/Playground/ServerMode/v1.0.0/TestingPlatformClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,9 @@ private sealed class TargetHandler
private readonly ConcurrentDictionary<Guid, ResponseListener> _listeners
= new();

private readonly ConcurrentBag<LogsCollector> _logListeners
= new();
private readonly ConcurrentBag<LogsCollector> _logListeners = [];

private readonly ConcurrentBag<TelemetryCollector> _telemetryPayloads
= new();
private readonly ConcurrentBag<TelemetryCollector> _telemetryPayloads = [];

public void RegisterTelemetryListener(TelemetryCollector listener)
=> _telemetryPayloads.Add(listener);
Expand Down
8 changes: 4 additions & 4 deletions src/Adapter/MSTest.Engine/Engine/BFSTestNodeVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ public BFSTestNodeVisitor(IEnumerable<TestNode> rootTestNodes, ITestExecutionFil
_testArgumentsManager = testArgumentsManager;
}

internal KeyValuePair<TestNodeUid, List<TestNode>>[] DuplicatedNodes { get; private set; } = Array.Empty<KeyValuePair<TestNodeUid, List<TestNode>>>();
internal KeyValuePair<TestNodeUid, List<TestNode>>[] DuplicatedNodes { get; private set; } = [];

public async Task VisitAsync(Func<TestNode, TestNodeUid?, Task> onIncludedTestNodeAsync)
{
// This is case sensitive, and culture insensitive, to keep UIDs unique, and comparable between different system.
Dictionary<TestNodeUid, List<TestNode>> testNodesByUid = new();
Dictionary<TestNodeUid, List<TestNode>> testNodesByUid = [];
Queue<(TestNode CurrentNode, TestNodeUid? ParentNodeUid, StringBuilder NodeFullPath)> queue = new();
foreach (TestNode node in _rootTestNodes)
{
Expand All @@ -47,7 +47,7 @@ public async Task VisitAsync(Func<TestNode, TestNodeUid?, Task> onIncludedTestNo

if (!testNodesByUid.TryGetValue(currentNode.StableUid, out List<TestNode>? testNodes))
{
testNodes = new();
testNodes = [];
testNodesByUid.Add(currentNode.StableUid, testNodes);
}

Expand Down Expand Up @@ -94,7 +94,7 @@ public async Task VisitAsync(Func<TestNode, TestNodeUid?, Task> onIncludedTestNo
}
}

DuplicatedNodes = testNodesByUid.Where(x => x.Value.Count > 1).ToArray();
DuplicatedNodes = [.. testNodesByUid.Where(x => x.Value.Count > 1)];
}

private static PropertyBag CreatePropertyBagForFilter(IProperty[] properties)
Expand Down
8 changes: 4 additions & 4 deletions src/Adapter/MSTest.Engine/Engine/TestArgumentsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.Testing.Framework;

internal sealed class TestArgumentsManager : ITestArgumentsManager
{
private readonly Dictionary<TestNodeUid, Func<TestArgumentsContext, ITestArgumentsEntry>> _testArgumentsEntryProviders = new();
private readonly Dictionary<TestNodeUid, Func<TestArgumentsContext, ITestArgumentsEntry>> _testArgumentsEntryProviders = [];
private bool _isRegistrationFrozen;

public void RegisterTestArgumentsEntryProvider<TArguments>(
Expand Down Expand Up @@ -53,8 +53,8 @@ internal async Task<TestNode> ExpandTestNodeAsync(TestNode currentNode)
};
}

HashSet<TestNodeUid> expandedTestNodeUids = new();
List<TestNode> expandedTestNodes = new(currentNode.Tests);
HashSet<TestNodeUid> expandedTestNodeUids = [];
List<TestNode> expandedTestNodes = [.. currentNode.Tests];
switch (currentNode)
{
case IParameterizedTestNode parameterizedTestNode:
Expand Down Expand Up @@ -98,7 +98,7 @@ internal async Task<TestNode> ExpandTestNodeAsync(TestNode currentNode)
DisplayName = currentNode.DisplayName,
OverriddenEdgeName = currentNode.OverriddenEdgeName,
Properties = currentNode.Properties,
Tests = expandedTestNodes.ToArray(),
Tests = [.. expandedTestNodes],
};

return expandedNode;
Expand Down
8 changes: 4 additions & 4 deletions src/Adapter/MSTest.Engine/Engine/TestFixtureManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ namespace Microsoft.Testing.Framework;

internal sealed class TestFixtureManager : ITestFixtureManager
{
private readonly Dictionary<FixtureId, Dictionary<Type, AsyncLazy<object>>> _fixtureInstancesByFixtureId = new();
private readonly Dictionary<TestNode, FixtureId[]> _fixtureIdsUsedByTestNode = new();
private readonly Dictionary<FixtureId, Dictionary<Type, AsyncLazy<object>>> _fixtureInstancesByFixtureId = [];
private readonly Dictionary<TestNode, FixtureId[]> _fixtureIdsUsedByTestNode = [];

// We could improve this by doing some optimistic lock but we expect a rather low contention on this.
// We use a dictionary as performance improvement because we know that when the registration is complete
// we will only read the collection (so no need for concurrency handling).
private readonly Dictionary<FixtureId, CountHolder> _fixtureUses = new();
private readonly Dictionary<FixtureId, CountHolder> _fixtureUses = [];
private readonly CancellationToken _cancellationToken;
private bool _isRegistrationFrozen;
private bool _isUsageRegistrationFrozen;
Expand Down Expand Up @@ -79,7 +79,7 @@ internal void RegisterFixtureUsage(TestNode testNode, string[] fixtureIds)
return;
}

_fixtureIdsUsedByTestNode.Add(testNode, fixtureIds.Select(x => new FixtureId(x)).ToArray());
_fixtureIdsUsedByTestNode.Add(testNode, [.. fixtureIds.Select(x => new FixtureId(x))]);
foreach (string fixtureId in fixtureIds)
{
if (!_fixtureUses.TryGetValue(fixtureId, out CountHolder? uses))
Expand Down
9 changes: 4 additions & 5 deletions src/Adapter/MSTest.Engine/Engine/TestFrameworkEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public TestFrameworkEngine(TestFrameworkConfiguration testFrameworkConfiguration
_configuration = new(configuration);
}

public Type[] DataTypesProduced { get; }
= new Type[1] { typeof(TestNodeUpdateMessage) };
public Type[] DataTypesProduced { get; } = [typeof(TestNodeUpdateMessage)];

public string Uid => _extension.Uid;

Expand All @@ -62,7 +61,7 @@ public async Task<Result> ExecuteRequestAsync(TestExecutionRequest testExecution
private async Task<Result> ExecuteTestNodeRunAsync(RunTestExecutionRequest request, IMessageBus messageBus,
CancellationToken cancellationToken)
{
List<TestNode> allRootTestNodes = new();
List<TestNode> allRootTestNodes = [];
TestFixtureManager fixtureManager = new(cancellationToken);
TestArgumentsManager argumentsManager = new();
TestSessionContext testSessionContext = new(_configuration, fixtureManager, argumentsManager, request.Session.SessionUid,
Expand Down Expand Up @@ -96,7 +95,7 @@ await testNodesVisitor.VisitAsync((testNode, parentTestNodeUid) =>
.OfType<FrameworkEngineMetadataProperty>()
.SingleOrDefault()
.UsedFixtureIds
?? Array.Empty<string>();
?? [];
fixtureManager.RegisterFixtureUsage(testNode, fixtureIds);

return Task.CompletedTask;
Expand Down Expand Up @@ -142,7 +141,7 @@ Task PublishDataAsync(IData data)
private async Task<Result> ExecuteTestNodeDiscoveryAsync(DiscoverTestExecutionRequest request, IMessageBus messageBus,
CancellationToken cancellationToken)
{
List<TestNode> allRootTestNodes = new();
List<TestNode> allRootTestNodes = [];
TestFixtureManager fixtureManager = new(cancellationToken);
TestArgumentsManager argumentsManager = new();
TestSessionContext testSessionContext = new(_configuration, fixtureManager, argumentsManager, request.Session.SessionUid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.Testing.Framework;
internal sealed class ThreadPoolTestNodeRunner : IDisposable
{
private readonly SemaphoreSlim? _maxParallelTests;
private readonly ConcurrentBag<Task<Result>> _runningTests = new();
private readonly ConcurrentBag<Task<Result>> _runningTests = [];
private readonly ConcurrentDictionary<TestNodeUid, int> _runningTestNodeUids = new();
private readonly CountdownEvent _ensureTaskQueuedCountdownEvent = new(1);
private readonly Func<IData, Task> _publishDataAsync;
Expand Down
2 changes: 1 addition & 1 deletion src/Adapter/MSTest.Engine/Helpers/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Microsoft.Testing.Framework;

internal sealed class Result
{
private readonly List<IReason> _reasons = new();
private readonly List<IReason> _reasons = [];

private Result()
{
Expand Down
4 changes: 2 additions & 2 deletions src/Adapter/MSTest.Engine/TestFramework/TestFramework.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ internal sealed class TestFramework : IDisposable, ITestFramework
private readonly TestingFrameworkExtension _extension;
private readonly CountdownEvent _incomingRequestCounter = new(1);
private readonly TestFrameworkEngine _engine;
private readonly List<string> _sessionWarningMessages = new();
private readonly List<string> _sessionErrorMessages = new();
private readonly List<string> _sessionWarningMessages = [];
private readonly List<string> _sessionErrorMessages = [];
private SessionUid? _sessionId;

public TestFramework(TestFrameworkConfiguration testFrameworkConfiguration, ITestNodesBuilder[] testNodesBuilders, TestingFrameworkExtension extension,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public TestFrameworkCapabilities(ITestNodesBuilder[] testNodesBuilders, IBannerM
}

public IReadOnlyCollection<ITestFrameworkCapability> Capabilities
=> new[] { new TestFrameworkCapabilitiesSet(_testNodesBuilders), _bannerMessageOwnerCapability };
=> [new TestFrameworkCapabilitiesSet(_testNodesBuilders), _bannerMessageOwnerCapability];
}

internal sealed class TestFrameworkCapabilitiesSet :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ public FactoryTestNodesBuilder(Func<TestNode[]> testNodesFactory)

public bool IsSupportingTrxProperties { get; }

IReadOnlyCollection<ITestFrameworkCapability> ICapabilities<ITestFrameworkCapability>.Capabilities
=> Array.Empty<ITestFrameworkCapability>();
IReadOnlyCollection<ITestFrameworkCapability> ICapabilities<ITestFrameworkCapability>.Capabilities => [];

public Task<TestNode[]> BuildAsync(ITestSessionContext _) => Task.FromResult(_testNodesFactory());
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ internal readonly struct FrameworkEngineMetadataProperty() : IProperty
{
public bool PreventArgumentsExpansion { get; init; }

public string[] UsedFixtureIds { get; init; } = Array.Empty<string>();
public string[] UsedFixtureIds { get; init; } = [];
}
4 changes: 2 additions & 2 deletions src/Adapter/MSTest.Engine/TestNodes/TestNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class TestNode
/// </summary>
public string? OverriddenEdgeName { get; init; }

public IProperty[] Properties { get; init; } = Array.Empty<IProperty>();
public IProperty[] Properties { get; init; } = [];

public TestNode[] Tests { get; init; } = Array.Empty<TestNode>();
public TestNode[] Tests { get; init; } = [];
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public AssemblyEnumerator(MSTestSettings settings) =>
/// <returns>A collection of Test Elements.</returns>
internal AssemblyEnumerationResult EnumerateAssembly(string assemblyFileName)
{
List<string> warnings = new();
List<string> warnings = [];
DebugEx.Assert(!StringEx.IsNullOrWhiteSpace(assemblyFileName), "Invalid assembly file name.");
var tests = new List<UnitTestElement>();
// Contains list of assembly/class names for which we have already added fixture tests.
Expand Down Expand Up @@ -350,7 +350,7 @@ private static bool TryUnfoldITestDataSources(UnitTestElement test, DiscoveryTes
IEnumerable<ITestDataSource> testDataSources = ReflectHelper.Instance.GetDerivedAttributes<Attribute>(testMethodInfo.MethodInfo, inherit: false).OfType<ITestDataSource>();

// We need to use a temporary list to avoid adding tests to the main list if we fail to expand any data source.
List<UnitTestElement> tempListOfTests = new();
List<UnitTestElement> tempListOfTests = [];

try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal sealed class AssemblyEnumeratorWrapper
/// <returns> A collection of test elements. </returns>
internal ICollection<UnitTestElement>? GetTests(string? assemblyFileName, IRunSettings? runSettings, out List<string> warnings)
{
warnings = new List<string>();
warnings = [];

if (StringEx.IsNullOrEmpty(assemblyFileName))
{
Expand Down
9 changes: 4 additions & 5 deletions src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,10 @@ internal List<UnitTestElement> GetTests(List<string> warnings)
currentType = currentType.BaseType;
}

return tests.GroupBy(
return [.. tests.GroupBy(
t => t.TestMethod.Name,
(_, elements) =>
elements.OrderBy(t => inheritanceDepths[t.TestMethod.DeclaringClassFullName ?? t.TestMethod.FullClassName]).First())
.ToList();
elements.OrderBy(t => inheritanceDepths[t.TestMethod.DeclaringClassFullName ?? t.TestMethod.FullClassName]).First())];
}

/// <summary>
Expand Down Expand Up @@ -169,7 +168,7 @@ internal UnitTestElement GetTestFromMethod(MethodInfo method, bool isDeclaredInT
traits.Add(priorityTrait);
}

testElement.Traits = traits.ToArray();
testElement.Traits = [.. traits];

Attribute[] attributes = _reflectHelper.GetCustomAttributesCached(method, inherit: true);
TestMethodAttribute? testMethodAttribute = null;
Expand Down Expand Up @@ -199,7 +198,7 @@ internal UnitTestElement GetTestFromMethod(MethodInfo method, bool isDeclaredInT
IEnumerable<WorkItemAttribute> workItemAttributes = attributes.OfType<WorkItemAttribute>();
if (workItemAttributes.Any())
{
testElement.WorkItemIds = workItemAttributes.Select(x => x.Id.ToString(CultureInfo.InvariantCulture)).ToArray();
testElement.WorkItemIds = [.. workItemAttributes.Select(x => x.Id.ToString(CultureInfo.InvariantCulture))];
}

// In production, we always have a TestMethod attribute because GetTestFromMethod is called under IsValidTestMethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal sealed class TestCaseDiscoverySink : ITestCaseDiscoverySink
/// <summary>
/// Gets the tests.
/// </summary>
public ICollection<TestCase> Tests { get; } = new List<TestCase>();
public ICollection<TestCase> Tests { get; } = [];

/// <summary>
/// Sends the test case.
Expand Down
12 changes: 6 additions & 6 deletions src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,25 +102,25 @@ internal set
/// Gets the timeout for the class initialize methods.
/// We can use a dictionary because the MethodInfo is unique in an inheritance hierarchy.
/// </summary>
internal Dictionary<MethodInfo, TimeoutInfo> ClassInitializeMethodTimeoutMilliseconds { get; } = new();
internal Dictionary<MethodInfo, TimeoutInfo> ClassInitializeMethodTimeoutMilliseconds { get; } = [];

/// <summary>
/// Gets the timeout for the class cleanup methods.
/// We can use a dictionary because the MethodInfo is unique in an inheritance hierarchy.
/// </summary>
internal Dictionary<MethodInfo, TimeoutInfo> ClassCleanupMethodTimeoutMilliseconds { get; } = new();
internal Dictionary<MethodInfo, TimeoutInfo> ClassCleanupMethodTimeoutMilliseconds { get; } = [];

/// <summary>
/// Gets the timeout for the test initialize methods.
/// We can use a dictionary because the MethodInfo is unique in an inheritance hierarchy.
/// </summary>
internal Dictionary<MethodInfo, TimeoutInfo> TestInitializeMethodTimeoutMilliseconds { get; } = new();
internal Dictionary<MethodInfo, TimeoutInfo> TestInitializeMethodTimeoutMilliseconds { get; } = [];

/// <summary>
/// Gets the timeout for the test cleanup methods.
/// We can use a dictionary because the MethodInfo is unique in an inheritance hierarchy.
/// </summary>
internal Dictionary<MethodInfo, TimeoutInfo> TestCleanupMethodTimeoutMilliseconds { get; } = new();
internal Dictionary<MethodInfo, TimeoutInfo> TestCleanupMethodTimeoutMilliseconds { get; } = [];

/// <summary>
/// Gets a value indicating whether class initialize has executed.
Expand All @@ -138,9 +138,9 @@ internal set
[Obsolete("API will be dropped in v4")]
public Stack<MethodInfo> BaseClassCleanupMethodsStack { get; } = new();

internal List<MethodInfo> BaseClassInitMethods { get; } = new();
internal List<MethodInfo> BaseClassInitMethods { get; } = [];

internal List<MethodInfo> BaseClassCleanupMethods { get; } = new();
internal List<MethodInfo> BaseClassCleanupMethods { get; } = [];

/// <summary>
/// Gets the exception thrown during <see cref="ClassInitializeAttribute"/> method invocation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,8 @@ private async Task ExecuteTestsInSourceAsync(IEnumerable<TestCase> tests, IRunCo

int parallelWorkers = sourceSettings.Workers;
ExecutionScope parallelScope = sourceSettings.Scope;
TestCase[] testsToRun = tests.Where(t => MatchTestFilter(filterExpression, t, _testMethodFilter)).ToArray();
UnitTestElement[] unitTestElements = testsToRun.Select(e => e.ToUnitTestElement(source)).ToArray();
TestCase[] testsToRun = [.. tests.Where(t => MatchTestFilter(filterExpression, t, _testMethodFilter))];
UnitTestElement[] unitTestElements = [.. testsToRun.Select(e => e.ToUnitTestElement(source))];
// Create an instance of a type defined in adapter so that adapter gets loaded in the child app domain
var testRunner = (UnitTestRunner)isolationHost.CreateInstanceForType(
typeof(UnitTestRunner),
Expand Down
Loading
Loading