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
4 changes: 2 additions & 2 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
},
{
"languageId": "csproj",
"words": ["buildtransitive", "contentfiles", "ruleset", "visualstudio"]
"words": ["buildtransitive", "contentfiles", "linq", "ruleset", "visualstudio"]
},
{
"languageId": "nuspec",
"words": ["netstandard", "schweizer"]
},
{
"languageId": "props",
"words": ["analyzers", "netstandard"]
"words": ["analyzers", "linq", "netstandard"]
}
],
"overrides": [
Expand Down
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ dotnet_style_require_accessibility_modifiers = for_
file_header_template = unset
indent_size = 4

dotnet_diagnostic.CA1034.severity = none
dotnet_diagnostic.CA2007.severity = none

[*.sh]
end_of_line = lf

Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 2.9.2

cleanup suppressions (mostly)

## 2.9.1

support injecting `ITestOutputHelper` (with some [Gotchas](./README.md#gotchas))
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageVersion Include="MinVer" Version="5.0.0" />
<PackageVersion Include="SimpleExec" Version="12.0.0" />
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
<PackageVersion Include="xunit" Version="2.9.0" />
<PackageVersion Include="xunit.extensibility.core" Version="2.9.0" />
<PackageVersion Include="xunit.extensibility.execution" Version="2.9.0" />
Expand Down
1 change: 1 addition & 0 deletions LambdaTale.sln
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{736B22BD-3BAB-41B7-A556-585A1839CE70}"
ProjectSection(SolutionItems) = preProject
Directory.Build.props = Directory.Build.props
Directory.Packages.props = Directory.Packages.props
EndProjectSection
EndProject
Global
Expand Down
4 changes: 1 addition & 3 deletions src/LambdaTale.Execution/Extensions/MethodInfoExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
Expand All @@ -9,13 +8,12 @@ namespace LambdaTale.Execution.Extensions;

internal static class MethodInfoExtensions
{
[SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj", Justification = "Propagating sync method parameter name.")]
public static async Task InvokeAsync(this MethodInfo method, object obj, object[] arguments)
{
method = method ?? throw new ArgumentNullException(nameof(method));

var parameterTypes = method.GetParameters().Select(parameter => parameter.ParameterType).ToArray();
Reflector.ConvertArguments(arguments, parameterTypes);
arguments = Reflector.ConvertArguments(arguments, parameterTypes);

if (method.Invoke(obj, arguments) is Task task)
{
Expand Down
4 changes: 0 additions & 4 deletions src/LambdaTale.Execution/GlobalSuppressions.cs

This file was deleted.

1 change: 0 additions & 1 deletion src/LambdaTale.Execution/Invoker.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
Expand Down
9 changes: 2 additions & 7 deletions src/LambdaTale.Execution/ScenarioInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,7 @@ private Task BeforeScenarioMethodInvokedAsync()
this.timer.Aggregate(() => beforeAfterAttribute.Before(this.scenarioMethod));
this.beforeAfterScenarioAttributesRun.Push(beforeAfterAttribute);
}
#pragma warning disable IDE0079 // Remove unnecessary suppression
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
#pragma warning restore IDE0079 // Remove unnecessary suppression
{
this.aggregator.Add(ex);
break;
Expand Down Expand Up @@ -237,13 +233,12 @@ private async Task<RunSummary> InvokeStepsAsync(
var stepTeardowns = stepContext.Disposables
.Where(disposable => disposable != null)
.Select((Func<IDisposable, Func<IStepContext, Task>>)(disposable =>
context =>
_ =>
{
disposable.Dispose();
return Task.CompletedTask;
}))
.Concat(stepDefinition.Teardowns)
.Where(teardown => teardown != null)
.Concat(stepDefinition.Teardowns.Where(teardown => teardown != null))
.Select(teardown => Tuple.Create(stepContext, teardown));

scenarioTeardowns.AddRange(stepTeardowns);
Expand Down
46 changes: 20 additions & 26 deletions src/LambdaTale.Execution/ScenarioOutlineTestCaseRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,31 @@

namespace LambdaTale.Execution;

public class ScenarioOutlineTestCaseRunner : XunitTestCaseRunner
public class ScenarioOutlineTestCaseRunner(
IMessageSink diagnosticMessageSink,
IXunitTestCase scenarioOutline,
string displayName,
string skipReason,
object[] constructorArguments,
IMessageBus messageBus,
ExceptionAggregator aggregator,
CancellationTokenSource cancellationTokenSource)
: XunitTestCaseRunner(scenarioOutline,
displayName,
skipReason,
constructorArguments,
NoArguments,
messageBus,
aggregator,
cancellationTokenSource)
{
private static readonly object[] noArguments = [];
private static readonly object[] NoArguments = [];

private readonly IMessageSink diagnosticMessageSink;
private readonly ExceptionAggregator cleanupAggregator = new();
private readonly List<ScenarioRunner> scenarioRunners = [];
private readonly List<IDisposable> disposables = [];
private Exception dataDiscoveryException;

public ScenarioOutlineTestCaseRunner(
IMessageSink diagnosticMessageSink,
IXunitTestCase scenarioOutline,
string displayName,
string skipReason,
object[] constructorArguments,
IMessageBus messageBus,
ExceptionAggregator aggregator,
CancellationTokenSource cancellationTokenSource)
: base(
scenarioOutline,
displayName,
skipReason,
constructorArguments,
noArguments,
messageBus,
aggregator,
cancellationTokenSource) => this.diagnosticMessageSink = diagnosticMessageSink;

protected override async Task AfterTestCaseStartingAsync()
{
await base.AfterTestCaseStartingAsync();
Expand All @@ -49,7 +45,7 @@ protected override async Task AfterTestCaseStartingAsync()
{
var discovererAttribute = dataAttribute.GetCustomAttributes(typeof(DataDiscovererAttribute)).First();
var discoverer =
ExtensibilityPointFactory.GetDataDiscoverer(this.diagnosticMessageSink, discovererAttribute);
ExtensibilityPointFactory.GetDataDiscoverer(diagnosticMessageSink, discovererAttribute);

foreach (var dataRow in discoverer.GetData(dataAttribute, this.TestCase.TestMethod.Method))
{
Expand All @@ -75,7 +71,7 @@ protected override async Task AfterTestCaseStartingAsync()

if (!this.scenarioRunners.Any())
{
var info = new ScenarioInfo(this.TestCase.TestMethod.Method, noArguments, this.DisplayName);
var info = new ScenarioInfo(this.TestCase.TestMethod.Method, NoArguments, this.DisplayName);
var test = new Scenario(this.TestCase, info.ScenarioDisplayName);
var runner = new ScenarioRunner(
test,
Expand All @@ -91,9 +87,7 @@ protected override async Task AfterTestCaseStartingAsync()
this.scenarioRunners.Add(runner);
}
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
{
this.dataDiscoveryException = ex;
}
Expand Down
2 changes: 0 additions & 2 deletions src/LambdaTale.Execution/StepTest.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
using System;
using System.Diagnostics.CodeAnalysis;
using LambdaTale.Sdk;
using Xunit;
using Xunit.Abstractions;

namespace LambdaTale.Execution;

[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Step", Justification = "By design.")]
public class StepTest : LongLivedMarshalByRefObject, IStep
{
public StepTest(IScenario scenario, string displayName)
Expand Down
57 changes: 23 additions & 34 deletions src/LambdaTale.Execution/StepTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,33 @@
using System.Threading;
using System.Threading.Tasks;
using LambdaTale.Sdk;
using Xunit.Abstractions;
using Xunit.Sdk;

namespace LambdaTale.Execution;

public class StepTestRunner : XunitTestRunner
public class StepTestRunner(
IStepContext stepContext,
Func<IStepContext, Task> body,
IMessageBus messageBus,
Type scenarioClass,
object[] constructorArguments,
MethodInfo scenarioMethod,
object[] scenarioMethodArguments,
string skipReason,
IReadOnlyList<BeforeAfterTestAttribute> beforeAfterAttributes,
ExceptionAggregator aggregator,
CancellationTokenSource cancellationTokenSource)
: XunitTestRunner(stepContext.Step,
messageBus,
scenarioClass,
constructorArguments,
scenarioMethod,
scenarioMethodArguments,
skipReason,
beforeAfterAttributes,
aggregator,
cancellationTokenSource)
{
private readonly IStepContext stepContext;
private readonly Func<IStepContext, Task> body;

public StepTestRunner(
IStepContext stepContext,
Func<IStepContext, Task> body,
IMessageBus messageBus,
Type scenarioClass,
object[] constructorArguments,
MethodInfo scenarioMethod,
object[] scenarioMethodArguments,
string skipReason,
IReadOnlyList<BeforeAfterTestAttribute> beforeAfterAttributes,
ExceptionAggregator aggregator,
CancellationTokenSource cancellationTokenSource)
: base(
stepContext.Step,
messageBus,
scenarioClass,
constructorArguments,
scenarioMethod,
scenarioMethodArguments,
skipReason,
beforeAfterAttributes,
aggregator,
cancellationTokenSource)
{
this.stepContext = stepContext;
this.body = body;
}

protected override Task<decimal> InvokeTestMethodAsync(ExceptionAggregator aggregator) =>
new StepInvoker(this.stepContext, this.body, aggregator, this.CancellationTokenSource).RunAsync();
new StepInvoker(stepContext, body, aggregator, this.CancellationTokenSource).RunAsync();
}
8 changes: 1 addition & 7 deletions src/LambdaTale/BackgroundAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
using System;
using System.Diagnostics.CodeAnalysis;

namespace LambdaTale;

/// <summary>
/// Applied to a method to indicate a background for each scenario defined in the same feature class.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
#pragma warning disable IDE0079 // Remove unnecessary suppression
[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "Designed for extensibility.")]
#pragma warning restore IDE0079 // Remove unnecessary suppression
[IgnoreXunitAnalyzersRule1013]
public class BackgroundAttribute : Attribute
{
[AttributeUsage(AttributeTargets.Class)]
private class IgnoreXunitAnalyzersRule1013Attribute : Attribute
{
}
private class IgnoreXunitAnalyzersRule1013Attribute : Attribute;
}
8 changes: 2 additions & 6 deletions src/LambdaTale/BeforeAfterScenarioAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Xunit.Sdk;

namespace LambdaTale;
Expand All @@ -15,8 +14,5 @@ namespace LambdaTale;
/// <see cref="BeforeAfterTestAttribute.After(System.Reflection.MethodInfo)" />
/// will be run before and after the scenario, rather than before and after each step in the scenario.
/// </remarks>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "Designed for extensibility.")]
public abstract class BeforeAfterScenarioAttribute : BeforeAfterTestAttribute
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public abstract class BeforeAfterScenarioAttribute : BeforeAfterTestAttribute;
25 changes: 4 additions & 21 deletions src/LambdaTale/ExampleAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Xunit.Sdk;

Expand All @@ -10,31 +9,15 @@ namespace LambdaTale;
/// Provides example values for a scenario passed as arguments to the scenario method.
/// This attribute is designed as a synonym of <see cref="Xunit.InlineDataAttribute"/>,
/// which is the most commonly used data attribute, but you can also use any type of attribute derived from
/// <see cref="Xunit.Sdk.DataAttribute"/> to provide a data source for a scenario.
/// <see cref="DataAttribute"/> to provide a data source for a scenario.
/// E.g. <see cref="Xunit.InlineDataAttribute"/> or
/// <see cref="Xunit.MemberDataAttribute"/>.
/// </summary>
/// /// <param name="data">The data values to pass to the scenario.</param>
[DataDiscoverer("Xunit.Sdk.InlineDataDiscoverer", "xunit.core")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
[SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification = "Following the pattern of Xunit.InlineDataAttribute.")]
public sealed class ExampleAttribute : DataAttribute
public sealed class ExampleAttribute(params object[] data) : DataAttribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ExampleAttribute"/> class.
/// This attribute is designed as a synonym of <see cref="Xunit.InlineDataAttribute"/>,
/// which is the most commonly used data attribute, but you can also use any type of attribute derived from
/// <see cref="Xunit.Sdk.DataAttribute"/> to provide a data source for a scenario.
/// E.g. <see cref="Xunit.InlineDataAttribute"/> or
/// <see cref="Xunit.MemberDataAttribute"/>.
/// </summary>
/// <param name="data">The data values to pass to the scenario.</param>
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "data", Justification = "Following the pattern of Xunit.InlineDataAttribute.")]
#pragma warning disable IDE0060 // Remove unused parameter
public ExampleAttribute(params object[] data)
#pragma warning restore IDE0060 // Remove unused parameter
{
}

/// <inheritdoc/>
public override IEnumerable<object[]> GetData(MethodInfo testMethod) => throw new InvalidOperationException();
public override IEnumerable<object[]> GetData(MethodInfo testMethod) => [data];
}
1 change: 0 additions & 1 deletion src/LambdaTale/LambdaTale.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);NU5128;CA1303</NoWarn>
<NuspecFile>$(NUSPEC_FILE)</NuspecFile>
</PropertyGroup>

Expand Down
6 changes: 4 additions & 2 deletions src/LambdaTale/LambdaTale.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
<tags>testing xunit</tags>
<version>$Version$</version>
<dependencies>
<dependency id="xunit.core" version="[2.9.0, 2.10)" />
<dependency id="xunit.extensibility.execution" version="[2.9.0, 2.10)" />
<group targetFramework=".NETStandard2.0">
<dependency id="xunit.core" version="[2.9.0, 2.10)" />
<dependency id="xunit.extensibility.execution" version="[2.9.0, 2.10)" />
</group>
</dependencies>
</metadata>
<files>
Expand Down
3 changes: 0 additions & 3 deletions src/LambdaTale/RemainingSteps.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using System.Diagnostics.CodeAnalysis;

namespace LambdaTale;

/// <summary>
/// Indicates the behavior of remaining steps when a step fails.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1717:OnlyFlagsEnumsShouldHavePluralNames", Justification = "Makes sense here.")]
public enum RemainingSteps
{
/// <summary>
Expand Down
Loading