Skip to content

Commit 4416784

Browse files
Consume new CCK Nuget package for Formatter tests; Upgraded dependencies to latest releases of Cucumber assets (#984)
* Upgraded dependencies to latest releases of Cucumber Gherkin 37.0.1, Messages 31.1.0 and HtmlFormatter 22.3.0. This supports the addition of the Location property to Pickles. Updated Formatters.Tests to use the latest release of the CCK scenarios and samples. * Update CHANGELOG.md * undo whitespace changes in Reqnroll.csproj * add PR number to CHANGELOG * Update Formatters.Tests samples to CCK v27 release (adds a new All-Statuses scenario and other minor restructuring) * Updated to Gherkin 38, Messages 32.0.1, and HtmlFormatter 23 * Eliminated (deleted) the CCK assets that will be provided by the CCK nuget package. * Add CCK package. * Modified tests to use the new path to the CCK assets. Adjusted test .csproj to embed the CCK assets in test output assembly. * Fixes to Formatters test infrastucture for using the new CCK package. Fixed Formatters to conform to Messages expectation that Pending steps have no error message text. Moved the 'all-statuses' scenario to NonCompliant until ambiguous step match arguments can be surfaced. * Fix Formatter.Tests csproj for cross-platform compatibility of embedding the CCK resources. * Fix test for ambiguous step matching * Fix CHANGELOG.md * Upgrade Cucumber.HtmlFormatter to v23.1.0 (and Messages to v32.3.1) to finalize the fix for the issue reported in #1035. Added a regression test to Formatters.Tests to demonstrate proper UTF-8 handling of attachments (as a non-CCK test). * Fix a OS-line-ending mistake in the regression test. * Update Gherkin and Cucumber.CCK package versions Updated Gherkin to 39.1.0 in Reqnroll.Parser.csproj and Cucumber.CCK to 29.2.2 in Reqnroll.Formatters.Tests.csproj. --------- Co-authored-by: Gáspár Nagy <gaspar.nagy@gmail.com>
1 parent 101392c commit 4416784

153 files changed

Lines changed: 482 additions & 2239 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# [vNext]
22

33
## Improvements:
4+
* Updated Cucumber dependencies to: Gherkin v39.1.0, Cucumber.Messages v32.0.1 and Cucumber.HtmlFormatter v23.1.0. Formatters.Tests modified by adopting use of Cucumber/CCK (v29.2.2). (#984)
45

56
## Bug fixes:
67

Reqnroll.Parser/Reqnroll.Parser.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
</PropertyGroup>
1212

1313
<ItemGroup>
14-
<PackageReference Include="Gherkin" Version="35.0.0" />
14+
<PackageReference Include="Gherkin" Version="39.1.0" />
1515
</ItemGroup>
1616

1717
<ItemGroup>

Reqnroll/Formatters/PayloadProcessing/Cucumber/CucumberMessageFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public virtual StepMatchArgument ToStepMatchArgument(TestStepArgument argument)
188188
{
189189
return new StepMatchArgument(
190190
new Group(
191-
[],
191+
null,
192192
argument.StartOffset,
193193
argument.Value
194194
),
@@ -316,7 +316,7 @@ private static string ToTestStepResultMessage(System.Exception exception, Scenar
316316
return status switch
317317
{
318318
ScenarioExecutionStatus.OK => null,
319-
ScenarioExecutionStatus.StepDefinitionPending => exception.Message,
319+
ScenarioExecutionStatus.StepDefinitionPending => null,
320320
ScenarioExecutionStatus.UndefinedStep => exception.Message,
321321
ScenarioExecutionStatus.BindingError => null,
322322
ScenarioExecutionStatus.TestError => exception.Message,

Reqnroll/Reqnroll.csproj

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,14 @@
1414
</PropertyGroup>
1515

1616
<ItemGroup>
17-
<ProjectReference
18-
Include="..\Reqnroll.Utils\Reqnroll.Utils.csproj"
19-
PackAsComponent="true"
20-
PrivateAssets="all" />
17+
<ProjectReference Include="..\Reqnroll.Utils\Reqnroll.Utils.csproj" PackAsComponent="true" PrivateAssets="all" />
2118
</ItemGroup>
2219

2320
<ItemGroup>
24-
<PackageReference Include="Gherkin" Version="35.0.0" />
21+
<PackageReference Include="Gherkin" Version="38.0.0" />
2522
<PackageReference Include="Cucumber.CucumberExpressions" Version="17.1.0" />
26-
<PackageReference Include="Cucumber.Messages" Version="30.1.0" />
27-
<PackageReference Include="Cucumber.HtmlFormatter" Version="22.2.0" />
23+
<PackageReference Include="Cucumber.Messages" Version="32.3.1" />
24+
<PackageReference Include="Cucumber.HtmlFormatter" Version="23.1.0" />
2825
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.6" />
2926
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="8.0.2" />
3027
<!-- System.Runtime.Loader is used for .NET (not .NET Framework) based frameworks only.
@@ -41,9 +38,7 @@
4138
</PropertyGroup>
4239

4340
<ItemGroup>
44-
<EmbeddedResource
45-
Include=".\BindingSkeletons\DefaultSkeletonTemplates.sftemplate"
46-
Exclude="bin\**;obj\**;**\*.xproj;packages\**;@(EmbeddedResource)" />
41+
<EmbeddedResource Include=".\BindingSkeletons\DefaultSkeletonTemplates.sftemplate" Exclude="bin\**;obj\**;**\*.xproj;packages\**;@(EmbeddedResource)" />
4742
</ItemGroup>
4843

4944
<!-- Ensure the instrumentation key template isn't included as source. -->
@@ -72,23 +67,15 @@
7267
</ItemGroup>
7368

7469
<!-- Embeds the Application Insights instrumentation key -->
75-
<Target
76-
Name="EmbedAppInsightsInstrumentationKey"
77-
Inputs="@(AppInsightsInstrumentationKeyFile)"
78-
Outputs="$(IntermediateOutputPath)%(AppInsightsInstrumentationKeyFile.Filename).$(AppInsightsInstrumentationKey)%(AppInsightsInstrumentationKeyFile.Extension)"
79-
BeforeTargets="CoreCompile">
70+
<Target Name="EmbedAppInsightsInstrumentationKey" Inputs="@(AppInsightsInstrumentationKeyFile)" Outputs="$(IntermediateOutputPath)%(AppInsightsInstrumentationKeyFile.Filename).$(AppInsightsInstrumentationKey)%(AppInsightsInstrumentationKeyFile.Extension)" BeforeTargets="CoreCompile">
8071

8172
<!-- Read the lines from the template. -->
8273
<ReadLinesFromFile File="%(AppInsightsInstrumentationKeyFile.Identity)">
8374
<Output TaskParameter="Lines" ItemName="_AppInsightsInstrumentationKeyFileTemplateLine" />
8475
</ReadLinesFromFile>
8576

8677
<!-- Produce the output file with the key token replaced. -->
87-
<WriteLinesToFile
88-
File="$(IntermediateOutputPath)%(AppInsightsInstrumentationKeyFile.Filename).$(AppInsightsInstrumentationKey)%(AppInsightsInstrumentationKeyFile.Extension)"
89-
Lines="@(_AppInsightsInstrumentationKeyFileTemplateLine -> Replace('_InstrumentationKey_', '$(AppInsightsInstrumentationKey)'))"
90-
Overwrite="true"
91-
Encoding="UTF-8" />
78+
<WriteLinesToFile File="$(IntermediateOutputPath)%(AppInsightsInstrumentationKeyFile.Filename).$(AppInsightsInstrumentationKey)%(AppInsightsInstrumentationKeyFile.Extension)" Lines="@(_AppInsightsInstrumentationKeyFileTemplateLine -&gt; Replace('_InstrumentationKey_', '$(AppInsightsInstrumentationKey)'))" Overwrite="true" Encoding="UTF-8" />
9279

9380
<ItemGroup>
9481
<!-- Include the file in the final build package -->

Tests/Reqnroll.Formatters.Tests/CucumberMessagesBasicTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ public void ExternalAssembliesAreSupportedInStepDefinitionMessages()
285285
CucumberMessagesAddConfigurationFile("reqnrollConfigurationWithExternalAssembly.json");
286286

287287
//Set up the Default Project (main test assembly)
288-
AddUtilClassWithFileSystemPath();
288+
AddUtilClassWithFileSystemPath("Samples");
289289

290290
AddFeatureFileFromResource($"ExternalBindingAssemblies/{featureNameText}.feature", "Samples", Assembly.GetExecutingAssembly());
291291
AddBindingClassFromResource($"ExternalBindingAssemblies/SampleInternalBindingClass.cs", "Samples", Assembly.GetExecutingAssembly());

Tests/Reqnroll.Formatters.Tests/MessagesCompatibilityTestBase.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,9 @@ protected void FileShouldExist(string v)
201201
File.Exists(file).Should().BeTrue(file, $"File {v} should exist");
202202
}
203203

204-
protected void AddUtilClassWithFileSystemPath()
204+
protected void AddUtilClassWithFileSystemPath(string pathsegment)
205205
{
206-
string location = Path.Combine(AppContext.BaseDirectory, "Samples", "Resources");
206+
string location = Path.Combine(AppContext.BaseDirectory, pathsegment, "Resources");
207207
AddBindingClass($$"""
208208
public class FileSystemPath
209209
{
@@ -212,9 +212,9 @@ public class FileSystemPath
212212
""");
213213
}
214214

215-
protected IEnumerable<Envelope> GetExpectedResults(string testName)
215+
protected IEnumerable<Envelope> GetExpectedResults(string testName, string source = "CCK")
216216
{
217-
string[] expectedJsonText = GetExpectedJsonText(testName);
217+
string[] expectedJsonText = GetExpectedJsonText(testName, source);
218218

219219
foreach (var json in expectedJsonText)
220220
{
@@ -223,11 +223,11 @@ protected IEnumerable<Envelope> GetExpectedResults(string testName)
223223
}
224224
}
225225

226-
protected string[] GetExpectedJsonText(string testName)
226+
protected string[] GetExpectedJsonText(string testName, string source)
227227
{
228228
var fileName = testName + "." + testName + ".ndjson";
229229
var assemblyToLoadFrom = Assembly.GetExecutingAssembly();
230-
var expectedJsonText = _testFileManager.GetTestFileContent(fileName, "Samples", assemblyToLoadFrom).Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
230+
var expectedJsonText = _testFileManager.GetTestFileContent(fileName, source, assemblyToLoadFrom).Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
231231
return expectedJsonText;
232232
}
233233

Tests/Reqnroll.Formatters.Tests/MessagesCompatibilityTests.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace Reqnroll.Formatters.Tests;
77
public class MessagesCompatibilityTests : MessagesCompatibilityTestBase
88
{
99
[TestMethod]
10+
[DataRow("all-statuses")]
1011
[DataRow("ambiguous")]
1112
[DataRow("backgrounds")]
1213
[DataRow("cdata")]
@@ -38,7 +39,7 @@ public class MessagesCompatibilityTests : MessagesCompatibilityTestBase
3839
// that are not material to the CCK spec (such as IDs don't have to be generated in the same order, timestamps don't have to match, etc.)
3940
// The rules for what must match and what is allowed to not match are built in to a series of custom FluentAssertion validation rules
4041
// (located in the CucumberMessagesValidator class)
41-
public void CCKScenarios(string testName)
42+
public void CCKScenarios(string testName, string featureFileSource = "CCK")
4243
{
4344
var featureFileName = testName.Replace("-", "_");
4445
ResetCucumberMessages(featureFileName);
@@ -48,14 +49,14 @@ public void CCKScenarios(string testName)
4849

4950
CucumberMessagesAddConfigurationFile("reqnroll_withBothFormatters.json");
5051
MimicAzurePipelinesEnvironment();
51-
AddUtilClassWithFileSystemPath();
52+
AddUtilClassWithFileSystemPath(featureFileSource);
5253

53-
AddFeatureFilesFromResources(featureFileName, "Samples", Assembly.GetExecutingAssembly());
54+
AddFeatureFilesFromResources(featureFileName, featureFileSource, Assembly.GetExecutingAssembly());
5455
AddBindingClassFromResource($"{featureFileName}/{featureFileName}.cs", "Samples", Assembly.GetExecutingAssembly());
5556

5657
ExecuteTests();
5758
var actualResults = GetActualResults(featureFileName).ToArray();
58-
var validator = new CucumberMessagesValidator(actualResults, GetExpectedResults(featureFileName).ToArray());
59+
var validator = new CucumberMessagesValidator(actualResults, GetExpectedResults(featureFileName, featureFileSource).ToArray());
5960
validator.ShouldPassBasicStructuralChecks();
6061
validator.ResultShouldPassAllComparisonTests();
6162
validator.ResultShouldPassSanityChecks();
@@ -80,13 +81,13 @@ public void CCKScenarios(string testName)
8081
ConfirmAllTestsRan(numOfTests);
8182
}
8283

83-
[Ignore]
8484
[TestMethod]
85+
[DataRow("Regression-RNR1035-NonASCIIcharactersinUTF8Attachment")]
8586
// These tests are not (yet) within the CCK but are included here to round out the testing. The expected results were generated by the CucumberMessages plugin.
8687
// Once the CCK includes these scenarios, the expected results should come from the CCK repo.
8788
public void NonCCKScenarios(string testName)
8889
{
89-
CCKScenarios(testName);
90+
CCKScenarios(testName, "Samples");
9091
}
9192

9293
[Ignore]
@@ -95,9 +96,11 @@ public void NonCCKScenarios(string testName)
9596
[DataRow("global-hooks-beforeall-error")] // Cucumber expects execution to continue after a hook failure
9697
[DataRow("global-hooks-afterall-error")] // Cucumber expects execution to continue after a hook failure
9798
[DataRow("global-hooks-attachments")] // Fails b/c we cannot obtain Reqnroll OutputHandler in global hooks
99+
[DataRow("hooks-skipped")] // Reqnroll terminates execution on first hook failure; Cucumber expects execution of other hooks continue after a hook failure
98100
[DataRow("unknown-parameter-type")] // Reqnroll does not provide skeletons for missing Parameter Types
99101
[DataRow("regular-expression")] // Reqnroll does not support optional binding method arguments
100102
[DataRow("multiple-features-reversed")] // Reqnroll does not have the concept of specifying execution order via run-time parameter
103+
[DataRow("test-run-exception")] // Reqnroll does not support a means of simulating a start-up failure
101104
// These scenarios are from the CCK, but Reqnroll cannot provide a compliant implementation. This is usually the result of differences in behavior or support of Gherkin features.
102105
// When these scenarios are run, expect them to fail.
103106
public void NonCompliantCCKScenarios(string testName)
@@ -128,6 +131,6 @@ public void CCKRetryScenario(string pluginName, string testNameRoot)
128131
_testRunConfiguration.UnitTestProvider = unitTestProvider;
129132
_projectsDriver.AddNuGetPackage(plugin, version);
130133
var testName = $"{pluginName}-{testNameRoot}";
131-
CCKScenarios(testName);
134+
CCKScenarios(testName, "Samples");
132135
}
133136
}

Tests/Reqnroll.Formatters.Tests/Reqnroll.Formatters.Tests.csproj

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,42 @@
88
<IsPackable>false</IsPackable>
99
<IsTestProject>true</IsTestProject>
1010
</PropertyGroup>
11-
11+
12+
<!-- This property is used by Cucumber.CCK as destination of the content files (e.g. .feature, .ndjson) for the tests. -->
13+
<PropertyGroup>
14+
<CucumberCCKContentPath>CCK/Resources</CucumberCCKContentPath>
15+
<EmbeddedCCKContentPathPrefix>$(CucumberCCKContentPath)/</EmbeddedCCKContentPathPrefix>
16+
</PropertyGroup>
17+
18+
<!-- Binding classes for scenarios come from the Samples\Resources tree.
19+
This tree also includes feature files and other assets for non-CCK scenarios. -->
1220
<ItemGroup>
1321
<Compile Remove="Samples\Resources\**\*.cs" />
14-
<None Remove="Samples\Resources\**\*.feature" />
15-
<None Remove="Samples\Resources\**\*.feature.ndjson" />
16-
<None Remove="Samples\Resources\**\*.ts" />
17-
<None Update="Samples\Resources\**\*.jpeg">
18-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
19-
</None>
20-
<None Update="Samples\Resources\**\*.png">
21-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
22-
</None>
23-
<None Update="Samples\Resources\**\*.pdf">
24-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
25-
</None>
26-
<None Update="Samples\Resources\**\*.svg">
27-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
28-
</None>
29-
<EmbeddedResource Include="Samples\Resources\**\*.cs" />
30-
<EmbeddedResource Include="Samples\Resources\**\*.feature" />
31-
<EmbeddedResource Include="Samples\Resources\**\*.ndjson" />
32-
<EmbeddedResource Include="Samples\Resources\**\*.csv" />
22+
<EmbeddedResource Include="Samples\Resources\**\*.*" />
3323
</ItemGroup>
3424

25+
<!-- This target embeds the feature files and other assets delivered by the Cucumber.CCK package. -->
26+
<Target Name="MakeCCKContentEmbeddedResource" AfterTargets="ResolvePackageAssets" BeforeTargets="CoreCompile">
27+
<ItemGroup>
28+
<!-- Step 1: Start with Content items that have Link metadata -->
29+
<_CCKContent Include="@(Content)" Condition="'%(Link)' != ''">
30+
<LinkNormalized>$([System.String]::Copy('%(Link)').Replace('\','/'))</LinkNormalized>
31+
</_CCKContent>
32+
33+
<!-- Step 2: Filter to only those matching the prefix -->
34+
<_CCKContent Update="@(_CCKContent)" Condition="$([System.String]::new('%(LinkNormalized)').StartsWith('$(EmbeddedCCKContentPathPrefix)'))" />
35+
36+
<!-- Step 3: Remove from Content and compute LogicalName -->
37+
<Content Remove="@(_CCKContent)" />
38+
<_CCKContent Update="@(_CCKContent)">
39+
<LogicalName>$(RootNamespace).$([System.String]::Copy('%(Link)').Replace('\','.').Replace('/','.').Replace('-','_'))</LogicalName>
40+
</_CCKContent>
41+
<EmbeddedResource Include="@(_CCKContent)" />
42+
</ItemGroup>
43+
</Target>
44+
3545
<ItemGroup>
46+
<PackageReference Include="Cucumber.CCK" Version="29.2.2" />
3647
<PackageReference Include="GitHubActionsTestLogger" Version="2.4.1" Condition="'$(REQNROLL_TEST_PIPELINEMODE)' == 'true'">
3748
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3849
<PrivateAssets>all</PrivateAssets>
@@ -45,8 +56,7 @@
4556
</ItemGroup>
4657

4758
<ItemGroup>
48-
<ProjectReference
49-
Include="..\..\Plugins\Reqnroll.ExternalData\Reqnroll.ExternalData.ReqnrollPlugin\Reqnroll.ExternalData.ReqnrollPlugin.csproj">
59+
<ProjectReference Include="..\..\Plugins\Reqnroll.ExternalData\Reqnroll.ExternalData.ReqnrollPlugin\Reqnroll.ExternalData.ReqnrollPlugin.csproj">
5060
<PrivateAssets>all</PrivateAssets>
5161
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
5262
</ProjectReference>

Tests/Reqnroll.Formatters.Tests/Samples/Resources/NUnitRetry-retry-pending/NUnitRetry_retry_pending.ndjson

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
{"testCase":{"id":"6","pickleId":"3","testSteps":[{"id":"7","pickleStepId":"2","stepDefinitionIds":["4"],"stepMatchArgumentsLists":[{"stepMatchArguments":[]}]}],"testRunStartedId":"5"}}
88
{"testCaseStarted":{"id":"8","testCaseId":"6","timestamp":{"seconds":0,"nanos":1000000},"attempt":0}}
99
{"testStepStarted":{"testCaseStartedId":"8","testStepId":"7","timestamp":{"seconds":0,"nanos":2000000}}}
10-
{"testStepFinished":{"testCaseStartedId":"8","testStepId":"7","testStepResult":{"status":"PENDING","message":"TODO","duration":{"seconds":0,"nanos":1000000}},"timestamp":{"seconds":0,"nanos":3000000}}}
10+
{"testStepFinished":{"testCaseStartedId":"8","testStepId":"7","testStepResult":{"status":"PENDING","duration":{"seconds":0,"nanos":1000000}},"timestamp":{"seconds":0,"nanos":3000000}}}
1111
{"testCaseFinished":{"testCaseStartedId":"8","timestamp":{"seconds":0,"nanos":4000000},"willBeRetried":false}}
1212
{"testRunFinished":{"testRunStartedId":"5","timestamp":{"seconds":0,"nanos":5000000},"success":false}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Reqnroll;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace CucumberMessages.CompatibilityTests.CCK.RegressionRNR1035NonASCIIcharactersinUTF8Attachment;
9+
10+
[Binding]
11+
internal class Attachments
12+
{
13+
private readonly IReqnrollOutputHelper reqnrollOutputHelper;
14+
15+
internal Attachments(IReqnrollOutputHelper reqnrollOutputHelper)
16+
{
17+
this.reqnrollOutputHelper = reqnrollOutputHelper;
18+
}
19+
20+
[When(@"attaching the non-ASCII string")]
21+
public void WhenAttachTextAs(string text)
22+
{
23+
// Normalize line endings to LF so the file content — and therefore
24+
// its Base64 encoding — is identical on Windows and Linux.
25+
var normalizedText = text.Replace("\r\n", "\n");
26+
27+
// write the string to a file as UTF-8 in current directory
28+
var fileName = $"Regression-RNR1035-NonASCIIcharactersinUTF8Attachment.txt";
29+
System.IO.File.WriteAllText(fileName, normalizedText, Encoding.UTF8);
30+
reqnrollOutputHelper.AddAttachment(fileName);
31+
}
32+
33+
}

0 commit comments

Comments
 (0)