From b12cb15a8403198614a1c16e38a51a82ad1d8194 Mon Sep 17 00:00:00 2001 From: Declan Smith Date: Wed, 24 Jun 2026 15:13:38 +1000 Subject: [PATCH] fix(github-action-writer): Fix string split for property writing --- .../GithubActionWriter.cs | 2 +- .../GithubActionWriterPropertyTests.cs | 75 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 tests/Invex.StructuredText.GithubActions.Tests/GithubActionWriterPropertyTests.cs diff --git a/src/Invex.StructuredText.GithubActions/GithubActionWriter.cs b/src/Invex.StructuredText.GithubActions/GithubActionWriter.cs index a45c059..37fbae7 100644 --- a/src/Invex.StructuredText.GithubActions/GithubActionWriter.cs +++ b/src/Invex.StructuredText.GithubActions/GithubActionWriter.cs @@ -811,7 +811,7 @@ private IDisposable WriteSection(string key, string value) => private void WriteProperty(string key, string value) { - var lines = value.Split('\r', '\n', StringSplitOptions.RemoveEmptyEntries); + var lines = value.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); switch (lines.Length) { diff --git a/tests/Invex.StructuredText.GithubActions.Tests/GithubActionWriterPropertyTests.cs b/tests/Invex.StructuredText.GithubActions.Tests/GithubActionWriterPropertyTests.cs new file mode 100644 index 0000000..c4b1a97 --- /dev/null +++ b/tests/Invex.StructuredText.GithubActions.Tests/GithubActionWriterPropertyTests.cs @@ -0,0 +1,75 @@ +namespace Invex.StructuredText.GithubActions.Tests; + +/// +/// Tests for how scalar properties are written, in particular multiline values that must be +/// emitted as YAML block scalars. These exercise the WriteProperty(string, string) path +/// via a job's env values. +/// +[TestFixture] +internal sealed class GithubActionWriterPropertyTests +{ + private static string WriteEnvValue(string value) + { + var job = GithubActionWriterHelper.MinimalJob() with + { + Env = new Dictionary + { + ["MY_VAR"] = new RawExpression(value), + }, + }; + + return GithubActionWriterHelper.Write(GithubActionWriterHelper.MinimalAction() with + { + Jobs = [job], + }); + } + + [Test] + public void WriteProperty_ValueWithLineFeedNewlines_WritesBlockScalar() + { + var output = WriteEnvValue("line1\nline2"); + + output.ShouldContain("MY_VAR: |"); + output.ShouldContain("line1"); + output.ShouldContain("line2"); + } + + [Test] + public void WriteProperty_ValueWithCarriageReturnNewlines_WritesBlockScalar() + { + var output = WriteEnvValue("line1\rline2"); + + output.ShouldContain("MY_VAR: |"); + output.ShouldContain("line1"); + output.ShouldContain("line2"); + } + + [Test] + public void WriteProperty_ValueWithCarriageReturnLineFeedNewlines_WritesBlockScalar() + { + var output = WriteEnvValue("line1\r\nline2"); + + output.ShouldContain("MY_VAR: |"); + output.ShouldContain("line1"); + output.ShouldContain("line2"); + } + + [Test] + public void WriteProperty_ValueWithLineFeedNewlines_DoesNotWriteValueInline() + { + var output = WriteEnvValue("line1\nline2"); + + // The buggy behaviour would emit "MY_VAR: line1\nline2" inline rather than a block scalar. + output.ShouldNotContain("MY_VAR: line1"); + } + + [Test] + public void WriteProperty_SingleLineValue_WritesInline() + { + var output = WriteEnvValue("hello"); + + output.ShouldContain("MY_VAR: hello"); + output.ShouldNotContain("MY_VAR: |"); + } +} +