Skip to content

Commit e38c0d4

Browse files
committed
Simplify YAML WriteValue by not preserving newlines
The YAML 1.2 spec says > Line breaks inside scalar content must be normalized by the YAML processor. Each such line break must be parsed into a single line feed character. The original line break format is a presentation detail and must not be used to convey content information. https://yaml.org/spec/1.2/spec.html#id2774608 Not preserving newlines simplifies the `OpenApiYamlWriter.WriteValue` and reduces number of test cases.
1 parent 7c46deb commit e38c0d4

File tree

2 files changed

+27
-50
lines changed

2 files changed

+27
-50
lines changed

src/Microsoft.OpenApi/Writers/OpenApiYamlWriter.cs

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -198,39 +198,24 @@ public override void WriteValue(string value)
198198

199199
IncreaseIndentation();
200200

201-
var start = 0;
202-
while (start < value.Length && value.IndexOfAny(new [] {'\n', '\r'}, start) is var lineBreak)
201+
using (var reader = new StringReader(value))
203202
{
204-
if (lineBreak == -1)
203+
bool firstLine = true;
204+
while (reader.ReadLine() is var line && line != null)
205205
{
206-
break;
206+
if (firstLine)
207+
firstLine = false;
208+
else
209+
Writer.WriteLine();
210+
211+
// Indentations for empty lines aren't needed.
212+
if (line.Length > 0)
213+
{
214+
WriteIndentation();
215+
}
216+
217+
Writer.Write(line);
207218
}
208-
209-
// To preserves line break characters.
210-
var end = lineBreak;
211-
if (lineBreak + 1 < value.Length && value[lineBreak] == '\r' && value[lineBreak + 1] == '\n')
212-
{
213-
// The line ends with "\r\n". YAML 1.2 specifies only three line breaks. "\r\n" | "\r" | "\n"
214-
end++;
215-
}
216-
217-
if (lineBreak - start != 0)
218-
{
219-
// Indentation for empty lines aren't needed.
220-
WriteIndentation();
221-
}
222-
223-
var line = value.Substring(start, end - start + 1);
224-
Writer.Write(line);
225-
226-
start = end + 1;
227-
}
228-
229-
// Last line
230-
if (start < value.Length)
231-
{
232-
WriteIndentation();
233-
Writer.Write(value.Substring(start));
234219
}
235220

236221
DecreaseIndentation();

test/Microsoft.OpenApi.Tests/Writers/OpenApiWriterSpecialCharacterTests.cs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,10 @@ public void WriteStringWithSpecialCharactersAsYamlWorks(string input, string exp
7777
}
7878

7979
[Theory]
80-
[InlineData("multiline\r\nstring", "test: |\n multiline\r\n string")]
81-
[InlineData("multiline\nstring", "test: |\n multiline\n string")]
82-
[InlineData("multiline\rstring", "test: |\n multiline\r string")]
83-
[InlineData("multiline\n\rstring", "test: |\n multiline\n\r string")]
84-
[InlineData("ends with\r\nline break\r\n", "test: |+\n ends with\r\n line break\r\n")]
85-
[InlineData("ends with\nline break\n", "test: |+\n ends with\n line break\n")]
86-
[InlineData("ends with\rline break\r", "test: |+\n ends with\r line break\r")]
87-
[InlineData("ends with\n\rline break\n\r", "test: |+\n ends with\n\r line break\n\r")]
80+
[InlineData("multiline\r\nstring", "test: |\n multiline\n string")]
81+
[InlineData("ends with\r\nline break\r\n", "test: |+\n ends with\n line break")]
8882
[InlineData(" starts with\nspaces", "test: |2\n starts with\n spaces")]
89-
[InlineData(" starts with\nspaces, and ends with line break\n", "test: |+2\n starts with\n spaces, and ends with line break\n")]
83+
[InlineData(" starts with\nspaces, and ends with line break\n", "test: |+2\n starts with\n spaces, and ends with line break")]
9084
[InlineData("contains\n\n\nempty lines", "test: |\n contains\n\n\n empty lines")]
9185
[InlineData("no line breaks fallback ", "test: 'no line breaks fallback '")]
9286
public void WriteStringWithNewlineCharactersInObjectAsYamlWorks(string input, string expected)
@@ -100,23 +94,19 @@ public void WriteStringWithNewlineCharactersInObjectAsYamlWorks(string input, st
10094
writer.WritePropertyName("test");
10195
writer.WriteValue(input);
10296
writer.WriteEndObject();
103-
var actual = outputStringWriter.GetStringBuilder().ToString();
97+
var actual = outputStringWriter.GetStringBuilder().ToString()
98+
// Normalize newline for cross platform
99+
.Replace("\r", "");
104100

105101
// Assert
106102
actual.Should().Be(expected);
107103
}
108104

109105
[Theory]
110-
[InlineData("multiline\r\nstring", "- |\n multiline\r\n string")]
111-
[InlineData("multiline\nstring", "- |\n multiline\n string")]
112-
[InlineData("multiline\rstring", "- |\n multiline\r string")]
113-
[InlineData("multiline\n\rstring", "- |\n multiline\n\r string")]
114-
[InlineData("ends with\r\nline break\r\n", "- |+\n ends with\r\n line break\r\n")]
115-
[InlineData("ends with\nline break\n", "- |+\n ends with\n line break\n")]
116-
[InlineData("ends with\rline break\r", "- |+\n ends with\r line break\r")]
117-
[InlineData("ends with\n\rline break\n\r", "- |+\n ends with\n\r line break\n\r")]
106+
[InlineData("multiline\r\nstring", "- |\n multiline\n string")]
107+
[InlineData("ends with\r\nline break\r\n", "- |+\n ends with\n line break")]
118108
[InlineData(" starts with\nspaces", "- |2\n starts with\n spaces")]
119-
[InlineData(" starts with\nspaces, and ends with line break\n", "- |+2\n starts with\n spaces, and ends with line break\n")]
109+
[InlineData(" starts with\nspaces, and ends with line break\n", "- |+2\n starts with\n spaces, and ends with line break")]
120110
[InlineData("contains\n\n\nempty lines", "- |\n contains\n\n\n empty lines")]
121111
[InlineData("no line breaks fallback ", "- 'no line breaks fallback '")]
122112
public void WriteStringWithNewlineCharactersInArrayAsYamlWorks(string input, string expected)
@@ -128,7 +118,9 @@ public void WriteStringWithNewlineCharactersInArrayAsYamlWorks(string input, str
128118
// Act
129119
writer.WriteStartArray();
130120
writer.WriteValue(input);
131-
var actual = outputStringWriter.GetStringBuilder().ToString();
121+
var actual = outputStringWriter.GetStringBuilder().ToString()
122+
// Normalize newline for cross platform
123+
.Replace("\r", "");
132124

133125
// Assert
134126
actual.Should().Be(expected);

0 commit comments

Comments
 (0)