// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Xunit.Abstractions; using Xunit.Sdk; namespace Templates.Test.Helpers.XunitExtensions { public class XunitTestAssemblyRunnerWithAssemblyFixture : XunitTestAssemblyRunner { private readonly Dictionary _assemblyFixtureMappings = new Dictionary(); public XunitTestAssemblyRunnerWithAssemblyFixture(ITestAssembly testAssembly, IEnumerable testCases, IMessageSink diagnosticMessageSink, IMessageSink executionMessageSink, ITestFrameworkExecutionOptions executionOptions) : base(testAssembly, testCases, diagnosticMessageSink, executionMessageSink, executionOptions) { } protected override async Task AfterTestAssemblyStartingAsync() { await base.AfterTestAssemblyStartingAsync(); // Find all the AssemblyFixtureAttributes on the test assembly Aggregator.Run(() => { var fixturesAttributes = ((IReflectionAssemblyInfo)TestAssembly.Assembly).Assembly .GetCustomAttributes(typeof(AssemblyFixtureAttribute), false) .Cast() .ToList(); // Instantiate all the fixtures foreach (var fixtureAttribute in fixturesAttributes) { _assemblyFixtureMappings[fixtureAttribute.FixtureType] = Activator.CreateInstance(fixtureAttribute.FixtureType); } }); } protected override Task BeforeTestAssemblyFinishedAsync() { // Dispose fixtures foreach (var disposable in _assemblyFixtureMappings.Values.OfType()) { Aggregator.Run(disposable.Dispose); } return base.BeforeTestAssemblyFinishedAsync(); } protected override Task RunTestCollectionAsync(IMessageBus messageBus, ITestCollection testCollection, IEnumerable testCases, CancellationTokenSource cancellationTokenSource) => new XunitTestCollectionRunnerWithAssemblyFixture( _assemblyFixtureMappings, testCollection, testCases, DiagnosticMessageSink, messageBus, TestCaseOrderer, new ExceptionAggregator(Aggregator), cancellationTokenSource).RunAsync(); } }