From f040de38649abf7bd9c96f970e6573324007485c Mon Sep 17 00:00:00 2001 From: Yousif Salah Date: Wed, 15 Jul 2026 14:57:51 +0300 Subject: [PATCH 1/3] Escape single quotes correctly in YAML CI writers --- .../CI/AzurePipelines/AzurePipelines.cs | 2 +- .../Configuration/AzurePipelinesCacheStep.cs | 2 +- .../Configuration/AzurePipelinesCmdStep.cs | 2 +- .../AzurePipelinesDownloadStep.cs | 2 +- .../Configuration/AzurePipelinesJob.cs | 4 +- .../AzurePipelinesPublishStep.cs | 4 +- .../Configuration/AzurePipelinesStage.cs | 4 +- .../GitHubActionsArtifactStep.cs | 2 +- .../Configuration/GitHubActionsCacheStep.cs | 4 +- .../Configuration/GitHubActionsRunStep.cs | 2 +- ...an_apostrophe_is_yaml_escaped.verified.txt | 4 ++ ...without_double_wrapping_quirk.verified.txt | 6 +++ .../CI/AzurePipelinesJobSpecs.cs | 44 +++++++++++++++++++ ...an_apostrophe_is_yaml_escaped.verified.txt | 5 +++ .../CI/GitHubActionsArtifactStepSpecs.cs | 26 +++++++++++ 15 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.DisplayName_with_an_apostrophe_is_yaml_escaped.verified.txt create mode 100644 tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.VmImage_is_quoted_correctly_without_double_wrapping_quirk.verified.txt create mode 100644 tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs create mode 100644 tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.Name_with_an_apostrophe_is_yaml_escaped.verified.txt create mode 100644 tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs diff --git a/src/Fallout.Common/CI/AzurePipelines/AzurePipelines.cs b/src/Fallout.Common/CI/AzurePipelines/AzurePipelines.cs index 93f66e267..f01d7b07e 100644 --- a/src/Fallout.Common/CI/AzurePipelines/AzurePipelines.cs +++ b/src/Fallout.Common/CI/AzurePipelines/AzurePipelines.cs @@ -175,7 +175,7 @@ public void PublishTestResults( .AddPairWhenValueNotNull("mergeResults", mergeResults) .AddPairWhenValueNotNull("platform", platform) .AddPairWhenValueNotNull("config", configuration) - .AddPairWhenValueNotNull("runTitle", title.SingleQuote()) + .AddPairWhenValueNotNull("runTitle", title.SingleQuoteYaml()) .AddPairWhenValueNotNull("publishRunAttachments", publishRunAttachments)); } diff --git a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesCacheStep.cs b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesCacheStep.cs index 555712c7b..f2eb1aa0d 100644 --- a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesCacheStep.cs +++ b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesCacheStep.cs @@ -27,7 +27,7 @@ public override void Write(CustomFileWriter writer) { using (writer.WriteBlock("- task: Cache@2")) { - writer.WriteLine("displayName: " + $"Cache: {Identifier}".SingleQuote()); + writer.WriteLine("displayName: " + $"Cache: {Identifier}".SingleQuoteYaml()); using (writer.WriteBlock("inputs:")) { writer.WriteLine($"key: $(Agent.OS) | {Identifier} | {KeyFiles.JoinCommaSpace()}"); diff --git a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesCmdStep.cs b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesCmdStep.cs index 1a9b7ed80..5b6783439 100644 --- a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesCmdStep.cs +++ b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesCmdStep.cs @@ -17,7 +17,7 @@ public override void Write(CustomFileWriter writer) { using (writer.WriteBlock("- task: CmdLine@2")) { - writer.WriteLine("displayName: " + $"Run: {InvokedTargets.JoinCommaSpace()}".SingleQuote()); + writer.WriteLine("displayName: " + $"Run: {InvokedTargets.JoinCommaSpace()}".SingleQuoteYaml()); var arguments = $"{InvokedTargets.JoinSpace()} --skip"; if (PartitionSize != null) diff --git a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesDownloadStep.cs b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesDownloadStep.cs index 759ff7fab..283d7b287 100644 --- a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesDownloadStep.cs +++ b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesDownloadStep.cs @@ -17,7 +17,7 @@ public override void Write(CustomFileWriter writer) using (writer.WriteBlock("inputs:")) { writer.WriteLine($"artifactName: {ArtifactName}"); - writer.WriteLine($"downloadPath: {DownloadPath.SingleQuote()}"); + writer.WriteLine($"downloadPath: {DownloadPath.SingleQuoteYaml()}"); } } } diff --git a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesJob.cs b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesJob.cs index 90ad9ba37..6af3caeaf 100644 --- a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesJob.cs +++ b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesJob.cs @@ -19,14 +19,14 @@ public override void Write(CustomFileWriter writer) { using (writer.WriteBlock($"- job: {Name}")) { - writer.WriteLine($"displayName: {DisplayName.SingleQuote()}"); + writer.WriteLine($"displayName: {DisplayName.SingleQuoteYaml()}"); writer.WriteLine($"dependsOn: [ {Dependencies.Select(x => x.Name).JoinCommaSpace()} ]"); if (Image != null) { using (writer.WriteBlock("pool:")) { - writer.WriteLine($"vmImage: {Image.Value.GetValue().SingleQuote().SingleQuote()}"); + writer.WriteLine($"vmImage: {Image.Value.GetValue().SingleQuoteYaml()}"); } } diff --git a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesPublishStep.cs b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesPublishStep.cs index de71af96a..834117f78 100644 --- a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesPublishStep.cs +++ b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesPublishStep.cs @@ -13,11 +13,11 @@ public override void Write(CustomFileWriter writer) { using (writer.WriteBlock("- task: PublishBuildArtifacts@1")) { - writer.WriteLine("displayName: " + $"Publish: {ArtifactName}".SingleQuote()); + writer.WriteLine("displayName: " + $"Publish: {ArtifactName}".SingleQuoteYaml()); using (writer.WriteBlock("inputs:")) { writer.WriteLine($"artifactName: {ArtifactName}"); - writer.WriteLine($"pathToPublish: {PathToPublish.SingleQuote()}"); + writer.WriteLine($"pathToPublish: {PathToPublish.SingleQuoteYaml()}"); } } } diff --git a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesStage.cs b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesStage.cs index 749858e6d..792366370 100644 --- a/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesStage.cs +++ b/src/Fallout.Common/CI/AzurePipelines/Configuration/AzurePipelinesStage.cs @@ -18,14 +18,14 @@ public override void Write(CustomFileWriter writer) { using (writer.WriteBlock($"- stage: {Name}")) { - writer.WriteLine($"displayName: {DisplayName.SingleQuote()}"); + writer.WriteLine($"displayName: {DisplayName.SingleQuoteYaml()}"); writer.WriteLine($"dependsOn: [ {Dependencies.Select(x => x.Name).JoinCommaSpace()} ]"); if (Image != null) { using (writer.WriteBlock("pool:")) { - writer.WriteLine($"vmImage: {Image.Value.GetValue().SingleQuote()}"); + writer.WriteLine($"vmImage: {Image.Value.GetValue().SingleQuoteYaml()}"); } } diff --git a/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsArtifactStep.cs b/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsArtifactStep.cs index ae5269c64..89ab0f9c1 100644 --- a/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsArtifactStep.cs +++ b/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsArtifactStep.cs @@ -12,7 +12,7 @@ public class GitHubActionsArtifactStep : GitHubActionsStep public override void Write(CustomFileWriter writer) { - writer.WriteLine("- name: " + $"Publish: {Name}".SingleQuote()); + writer.WriteLine("- name: " + $"Publish: {Name}".SingleQuoteYaml()); writer.WriteLine(" uses: actions/upload-artifact@v5"); using (writer.Indent()) diff --git a/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsCacheStep.cs b/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsCacheStep.cs index d1fb7da89..2fc5b3517 100644 --- a/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsCacheStep.cs +++ b/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsCacheStep.cs @@ -14,7 +14,7 @@ public class GitHubActionsCacheStep : GitHubActionsStep public override void Write(CustomFileWriter writer) { - writer.WriteLine("- name: " + $"Cache: {IncludePatterns.JoinCommaSpace()}".SingleQuote()); + writer.WriteLine("- name: " + $"Cache: {IncludePatterns.JoinCommaSpace()}".SingleQuoteYaml()); using (writer.Indent()) { writer.WriteLine("uses: actions/cache@v4"); @@ -24,7 +24,7 @@ public override void Write(CustomFileWriter writer) writer.WriteLine("path: |"); IncludePatterns.ForEach(x => writer.WriteLine($" {x}")); ExcludePatterns.ForEach(x => writer.WriteLine($" !{x}")); - writer.WriteLine($"key: ${{{{ runner.os }}}}-${{{{ hashFiles({KeyFiles.Select(x => x.SingleQuote()).JoinCommaSpace()}) }}}}"); + writer.WriteLine($"key: ${{{{ runner.os }}}}-${{{{ hashFiles({KeyFiles.Select(x => x.SingleQuoteYaml()).JoinCommaSpace()}) }}}}"); } } } diff --git a/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsRunStep.cs b/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsRunStep.cs index 5ff03f0cb..1b774eefb 100644 --- a/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsRunStep.cs +++ b/src/Fallout.Common/CI/GitHubActions/Configuration/GitHubActionsRunStep.cs @@ -28,7 +28,7 @@ public override void Write(CustomFileWriter writer) writer.WriteLine("run: dotnet tool restore"); } - writer.WriteLine("- name: " + $"Run: {InvokedTargets.JoinCommaSpace()}".SingleQuote()); + writer.WriteLine("- name: " + $"Run: {InvokedTargets.JoinCommaSpace()}".SingleQuoteYaml()); using (writer.Indent()) { writer.WriteLine($"run: dotnet fallout {InvokedTargets.JoinSpace()}"); diff --git a/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.DisplayName_with_an_apostrophe_is_yaml_escaped.verified.txt b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.DisplayName_with_an_apostrophe_is_yaml_escaped.verified.txt new file mode 100644 index 000000000..478ede08c --- /dev/null +++ b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.DisplayName_with_an_apostrophe_is_yaml_escaped.verified.txt @@ -0,0 +1,4 @@ +- job: Compile + displayName: 'Yousif''s Job' + dependsOn: [ ] + steps: diff --git a/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.VmImage_is_quoted_correctly_without_double_wrapping_quirk.verified.txt b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.VmImage_is_quoted_correctly_without_double_wrapping_quirk.verified.txt new file mode 100644 index 000000000..929ea4fb4 --- /dev/null +++ b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.VmImage_is_quoted_correctly_without_double_wrapping_quirk.verified.txt @@ -0,0 +1,6 @@ +- job: Compile + displayName: 'Compile Job' + dependsOn: [ ] + pool: + vmImage: 'ubuntu-22.04' + steps: diff --git a/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs new file mode 100644 index 000000000..5f75fe895 --- /dev/null +++ b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs @@ -0,0 +1,44 @@ +using System.IO; +using System.Threading.Tasks; +using Fallout.Common.CI.AzurePipelines; +using Fallout.Common.CI.AzurePipelines.Configuration; +using Fallout.Common.Utilities; +using VerifyXunit; +using Xunit; + +namespace Fallout.Common.Specs.CI; + +public class AzurePipelinesJobSpecs +{ + private static Task Verify(AzurePipelinesJob job) + { + var stream = new MemoryStream(); + var writer = new StreamWriter(stream, leaveOpen: true); + job.Write(new CustomFileWriter(writer, indentationFactor: 2, commentPrefix: "#")); + writer.Flush(); + + stream.Seek(offset: 0, SeekOrigin.Begin); + return Verifier.Verify(new StreamReader(stream).ReadToEnd()); + } + + [Fact] + public Task DisplayName_with_an_apostrophe_is_yaml_escaped() + => Verify(new AzurePipelinesJob + { + Name = "Compile", + DisplayName = "Yousif's Job", + Dependencies = new AzurePipelinesJob[0], + Steps = new AzurePipelinesStep[0] + }); + + [Fact] + public Task VmImage_is_quoted_correctly_without_double_wrapping_quirk() + => Verify(new AzurePipelinesJob + { + Name = "Compile", + DisplayName = "Compile Job", + Dependencies = new AzurePipelinesJob[0], + Steps = new AzurePipelinesStep[0], + Image = AzurePipelinesImage.Ubuntu2204 + }); +} diff --git a/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.Name_with_an_apostrophe_is_yaml_escaped.verified.txt b/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.Name_with_an_apostrophe_is_yaml_escaped.verified.txt new file mode 100644 index 000000000..ea390b2c0 --- /dev/null +++ b/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.Name_with_an_apostrophe_is_yaml_escaped.verified.txt @@ -0,0 +1,5 @@ +- name: 'Publish: Yousif''s Build' + uses: actions/upload-artifact@v5 + with: + name: Yousif's Build + path: out diff --git a/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs b/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs new file mode 100644 index 000000000..778a2782a --- /dev/null +++ b/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs @@ -0,0 +1,26 @@ +using System.IO; +using System.Threading.Tasks; +using Fallout.Common.CI.GitHubActions.Configuration; +using Fallout.Common.Utilities; +using VerifyXunit; +using Xunit; + +namespace Fallout.Common.Specs.CI; + +public class GitHubActionsArtifactStepSpecs +{ + private static Task Verify(GitHubActionsArtifactStep step) + { + var stream = new MemoryStream(); + var writer = new StreamWriter(stream, leaveOpen: true); + step.Write(new CustomFileWriter(writer, indentationFactor: 2, commentPrefix: "#")); + writer.Flush(); + + stream.Seek(offset: 0, SeekOrigin.Begin); + return Verifier.Verify(new StreamReader(stream).ReadToEnd()); + } + + [Fact] + public Task Name_with_an_apostrophe_is_yaml_escaped() + => Verify(new GitHubActionsArtifactStep { Name = "Yousif's Build", Path = "out", Condition = "" }); +} From a598d0ee957555a8a03e7e296736da80228c1397 Mon Sep 17 00:00:00 2001 From: Yousif Salah Date: Wed, 15 Jul 2026 16:23:02 +0300 Subject: [PATCH 2/3] Rename test names to generic examples per review --- ...isplayName_with_an_apostrophe_is_yaml_escaped.verified.txt | 2 +- tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs | 2 +- ...Specs.Name_with_an_apostrophe_is_yaml_escaped.verified.txt | 4 ++-- .../Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.DisplayName_with_an_apostrophe_is_yaml_escaped.verified.txt b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.DisplayName_with_an_apostrophe_is_yaml_escaped.verified.txt index 478ede08c..7075637e4 100644 --- a/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.DisplayName_with_an_apostrophe_is_yaml_escaped.verified.txt +++ b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.DisplayName_with_an_apostrophe_is_yaml_escaped.verified.txt @@ -1,4 +1,4 @@ - job: Compile - displayName: 'Yousif''s Job' + displayName: 'Bob''s Job' dependsOn: [ ] steps: diff --git a/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs index 5f75fe895..a9dacbe3b 100644 --- a/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs +++ b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs @@ -26,7 +26,7 @@ public Task DisplayName_with_an_apostrophe_is_yaml_escaped() => Verify(new AzurePipelinesJob { Name = "Compile", - DisplayName = "Yousif's Job", + DisplayName = "Bob's Job", Dependencies = new AzurePipelinesJob[0], Steps = new AzurePipelinesStep[0] }); diff --git a/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.Name_with_an_apostrophe_is_yaml_escaped.verified.txt b/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.Name_with_an_apostrophe_is_yaml_escaped.verified.txt index ea390b2c0..66a15cb24 100644 --- a/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.Name_with_an_apostrophe_is_yaml_escaped.verified.txt +++ b/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.Name_with_an_apostrophe_is_yaml_escaped.verified.txt @@ -1,5 +1,5 @@ -- name: 'Publish: Yousif''s Build' +- name: 'Publish: Bob''s Build' uses: actions/upload-artifact@v5 with: - name: Yousif's Build + name: Bob's Build path: out diff --git a/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs b/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs index 778a2782a..858d83422 100644 --- a/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs +++ b/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs @@ -22,5 +22,5 @@ private static Task Verify(GitHubActionsArtifactStep step) [Fact] public Task Name_with_an_apostrophe_is_yaml_escaped() - => Verify(new GitHubActionsArtifactStep { Name = "Yousif's Build", Path = "out", Condition = "" }); + => Verify(new GitHubActionsArtifactStep { Name = "Bob's Build", Path = "out", Condition = "" }); } From 01ba1e9fd7cb5baf4467508aeb9e1d588d512a1d Mon Sep 17 00:00:00 2001 From: Yousif Salah Date: Wed, 15 Jul 2026 16:39:46 +0300 Subject: [PATCH 3/3] Extract shared Verify helper for configuration specs --- .../CI/AzurePipelinesJobSpecs.cs | 17 ++------------- .../CI/ConfigurationEntityVerifier.cs | 21 +++++++++++++++++++ .../CI/GitHubActionsArtifactStepSpecs.cs | 15 +------------ 3 files changed, 24 insertions(+), 29 deletions(-) create mode 100644 tests/Fallout.Common.Specs/CI/ConfigurationEntityVerifier.cs diff --git a/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs index a9dacbe3b..1bdefe3cd 100644 --- a/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs +++ b/tests/Fallout.Common.Specs/CI/AzurePipelinesJobSpecs.cs @@ -2,28 +2,15 @@ using System.Threading.Tasks; using Fallout.Common.CI.AzurePipelines; using Fallout.Common.CI.AzurePipelines.Configuration; -using Fallout.Common.Utilities; -using VerifyXunit; using Xunit; namespace Fallout.Common.Specs.CI; public class AzurePipelinesJobSpecs { - private static Task Verify(AzurePipelinesJob job) - { - var stream = new MemoryStream(); - var writer = new StreamWriter(stream, leaveOpen: true); - job.Write(new CustomFileWriter(writer, indentationFactor: 2, commentPrefix: "#")); - writer.Flush(); - - stream.Seek(offset: 0, SeekOrigin.Begin); - return Verifier.Verify(new StreamReader(stream).ReadToEnd()); - } - [Fact] public Task DisplayName_with_an_apostrophe_is_yaml_escaped() - => Verify(new AzurePipelinesJob + => ConfigurationEntityVerifier.Verify(new AzurePipelinesJob { Name = "Compile", DisplayName = "Bob's Job", @@ -33,7 +20,7 @@ public Task DisplayName_with_an_apostrophe_is_yaml_escaped() [Fact] public Task VmImage_is_quoted_correctly_without_double_wrapping_quirk() - => Verify(new AzurePipelinesJob + => ConfigurationEntityVerifier.Verify(new AzurePipelinesJob { Name = "Compile", DisplayName = "Compile Job", diff --git a/tests/Fallout.Common.Specs/CI/ConfigurationEntityVerifier.cs b/tests/Fallout.Common.Specs/CI/ConfigurationEntityVerifier.cs new file mode 100644 index 000000000..cdc035f91 --- /dev/null +++ b/tests/Fallout.Common.Specs/CI/ConfigurationEntityVerifier.cs @@ -0,0 +1,21 @@ +using System.IO; +using System.Threading.Tasks; +using Fallout.Common.CI; +using Fallout.Common.Utilities; +using VerifyXunit; + +namespace Fallout.Common.Specs.CI; + +public static class ConfigurationEntityVerifier +{ + public static Task Verify(ConfigurationEntity entity) + { + var stream = new MemoryStream(); + var writer = new StreamWriter(stream, leaveOpen: true); + entity.Write(new CustomFileWriter(writer, indentationFactor: 2, commentPrefix: "#")); + writer.Flush(); + + stream.Seek(offset: 0, SeekOrigin.Begin); + return Verifier.Verify(new StreamReader(stream).ReadToEnd()); + } +} diff --git a/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs b/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs index 858d83422..929e59291 100644 --- a/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs +++ b/tests/Fallout.Common.Specs/CI/GitHubActionsArtifactStepSpecs.cs @@ -1,26 +1,13 @@ using System.IO; using System.Threading.Tasks; using Fallout.Common.CI.GitHubActions.Configuration; -using Fallout.Common.Utilities; -using VerifyXunit; using Xunit; namespace Fallout.Common.Specs.CI; public class GitHubActionsArtifactStepSpecs { - private static Task Verify(GitHubActionsArtifactStep step) - { - var stream = new MemoryStream(); - var writer = new StreamWriter(stream, leaveOpen: true); - step.Write(new CustomFileWriter(writer, indentationFactor: 2, commentPrefix: "#")); - writer.Flush(); - - stream.Seek(offset: 0, SeekOrigin.Begin); - return Verifier.Verify(new StreamReader(stream).ReadToEnd()); - } - [Fact] public Task Name_with_an_apostrophe_is_yaml_escaped() - => Verify(new GitHubActionsArtifactStep { Name = "Bob's Build", Path = "out", Condition = "" }); + => ConfigurationEntityVerifier.Verify(new GitHubActionsArtifactStep { Name = "Bob's Build", Path = "out", Condition = "" }); }