public static async ValueTask IsXunit()
        {
            await using var context = TestableXunitTestAssemblyRunnerContext.Create();
            await context.InitializeAsync();

            var result = context.TestFrameworkDisplayName;

            Assert.StartsWith("xUnit.net v3 ", result);
        }
        public static async ValueTask Default()
        {
            await using var context = TestableXunitTestAssemblyRunnerContext.Create();
            await context.InitializeAsync();

            var result = context.TestFrameworkEnvironment;

            Assert.EndsWith($"[collection-per-class, parallel ({Environment.ProcessorCount} threads)]", result);
        }
        public static async ValueTask Attribute_CollectionBehavior(CollectionBehavior behavior, string expectedDisplayText)
        {
            var attribute = Mocks.CollectionBehaviorAttribute(behavior, disableTestParallelization: true);
            var assembly  = Mocks.TestAssembly("assembly.dll", assemblyAttributes: new[] { attribute });

            await using var context = TestableXunitTestAssemblyRunnerContext.Create(assembly: assembly);
            await context.InitializeAsync();

            var result = context.TestFrameworkEnvironment;

            Assert.EndsWith($"[{expectedDisplayText}, non-parallel]", result);
        }
        public static async ValueTask Attribute_Unlimited()
        {
            var attribute = Mocks.CollectionBehaviorAttribute(maxParallelThreads: -1);
            var assembly  = Mocks.TestAssembly("assembly.dll", assemblyAttributes: new[] { attribute });

            await using var context = TestableXunitTestAssemblyRunnerContext.Create(assembly: assembly);
            await context.InitializeAsync();

            var result = context.TestFrameworkEnvironment;

            Assert.EndsWith("[collection-per-class, parallel (unlimited threads)]", result);
        }
        public static async ValueTask Attribute_NonParallel()
        {
            var attribute = Mocks.CollectionBehaviorAttribute(disableTestParallelization: true);
            var assembly  = Mocks.TestAssembly("assembly.dll", assemblyAttributes: new[] { attribute });

            await using var context = TestableXunitTestAssemblyRunnerContext.Create(assembly: assembly);
            await context.InitializeAsync();

            var result = context.TestFrameworkEnvironment;

            Assert.EndsWith("[collection-per-class, non-parallel]", result);
        }
        public static async ValueTask CanSetTestCollectionOrdererInAssemblyAttribute()
        {
            var ordererAttribute = Mocks.TestCollectionOrdererAttribute <DescendingDisplayNameCollectionOrderer>();
            var assembly         = Mocks.TestAssembly("assembly.dll", assemblyAttributes: new[] { ordererAttribute });

            await using var context = TestableXunitTestAssemblyRunnerContext.Create(assembly: assembly);
            await context.InitializeAsync();

            var result = context.AssemblyTestCollectionOrderer;

            Assert.IsType <DescendingDisplayNameCollectionOrderer>(result);
        }
        public static async ValueTask TestOptions_Unlimited()
        {
            var options = _TestFrameworkOptions.ForExecution();

            options.SetMaxParallelThreads(-1);
            await using var context = TestableXunitTestAssemblyRunnerContext.Create(executionOptions: options);
            await context.InitializeAsync();

            var result = context.TestFrameworkEnvironment;

            Assert.EndsWith("[collection-per-class, parallel (unlimited threads)]", result);
        }
        public static async ValueTask TestOptions_NonParallel()
        {
            var options = _TestFrameworkOptions.ForExecution();

            options.SetDisableParallelization(true);
            await using var context = TestableXunitTestAssemblyRunnerContext.Create(executionOptions: options);
            await context.InitializeAsync();

            var result = context.TestFrameworkEnvironment;

            Assert.EndsWith("[collection-per-class, non-parallel]", result);
        }
        public static async ValueTask Attribute_CustomCollectionFactory()
        {
            var factoryType = typeof(MyTestCollectionFactory);
            var attr        = Mocks.CollectionBehaviorAttribute(factoryType.FullName !, factoryType.Assembly.FullName !, disableTestParallelization: true);
            var assembly    = Mocks.TestAssembly("assembly.dll", assemblyAttributes: new[] { attr });

            await using var context = TestableXunitTestAssemblyRunnerContext.Create(assembly: assembly);
            await context.InitializeAsync();

            var result = context.TestFrameworkEnvironment;

            Assert.EndsWith("[My Factory, non-parallel]", result);
        }
        public static async ValueTask TestOptionsOverrideAttribute()
        {
            var attribute = Mocks.CollectionBehaviorAttribute(disableTestParallelization: true, maxParallelThreads: 127);
            var options   = _TestFrameworkOptions.ForExecution();

            options.SetDisableParallelization(false);
            options.SetMaxParallelThreads(3);
            var assembly = Mocks.TestAssembly("assembly.dll", assemblyAttributes: new[] { attribute });

            await using var context = TestableXunitTestAssemblyRunnerContext.Create(assembly: assembly, executionOptions: options);
            await context.InitializeAsync();

            var result = context.TestFrameworkEnvironment;

            Assert.EndsWith("[collection-per-class, parallel (3 threads)]", result);
        }
        public static async ValueTask SettingTestCollectionOrdererWithThrowingConstructorLogsDiagnosticMessage()
        {
            var spy = SpyMessageSink.Capture();

            TestContext.Current !.DiagnosticMessageSink = spy;

            var ordererAttribute = Mocks.TestCollectionOrdererAttribute <CtorThrowingCollectionOrderer>();
            var assembly         = Mocks.TestAssembly("assembly.dll", assemblyAttributes: new[] { ordererAttribute });

            await using var context = TestableXunitTestAssemblyRunnerContext.Create(assembly: assembly);
            await context.InitializeAsync();

            var result = context.AssemblyTestCollectionOrderer;

            Assert.Null(result);
            var diagnosticMessage = Assert.Single(spy.Messages.OfType <_DiagnosticMessage>());

            Assert.StartsWith($"Assembly-level test collection orderer '{typeof(CtorThrowingCollectionOrderer).FullName}' threw 'System.DivideByZeroException' during construction: Attempted to divide by zero.", diagnosticMessage.Message);
        }
        public static async ValueTask SettingUnknownTestCollectionOrderLogsDiagnosticMessage()
        {
            var spy = SpyMessageSink.Capture();

            TestContext.Current !.DiagnosticMessageSink = spy;

            var ordererAttribute = Mocks.TestCollectionOrdererAttribute("UnknownType", "UnknownAssembly");
            var assembly         = Mocks.TestAssembly("assembly.dll", assemblyAttributes: new[] { ordererAttribute });

            await using var context = TestableXunitTestAssemblyRunnerContext.Create(assembly: assembly);
            await context.InitializeAsync();

            var result = context.AssemblyTestCollectionOrderer;

            Assert.Null(result);
            var diagnosticMessage = Assert.Single(spy.Messages.OfType <_DiagnosticMessage>());

            Assert.Equal("Could not find type 'UnknownType' in UnknownAssembly for assembly-level test collection orderer", diagnosticMessage.Message);
        }