Skip to content

Commit

Permalink
Fix some issues with comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
aaubry committed Sep 16, 2016
1 parent 5d99489 commit a662fe5
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 3 deletions.
17 changes: 17 additions & 0 deletions YamlDotNet.Test/Core/EmitterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,23 @@ public void CommentsAreEmittedCorrectly()
.And.Contain("# Bottom comment");
}

[Fact]
public void ACommentAsTheFirstEventAddsANewLine()
{
var events = new ParsingEvent[]
{
StandaloneComment("Top comment"),
Scalar("first").ImplicitPlain,
};

var yaml = EmittedTextFrom(StreamedDocumentWith(events));

yaml.Should()
.Contain("# Top comment")
.And.Contain("first")
.And.NotContain("# Top commentfirst");
}

[Theory]
[InlineData("Гранит", 28595)] // Cyrillic (ISO)
[InlineData("ГÀƊȽ˱ώҔׂۋᵷẁό₩וּﺪﺸﻸﭧ╬♫₹Ὰỗ᷁ݭ٭ӢР͞ʓLjĄë0", 65001)] // UTF-8
Expand Down
2 changes: 1 addition & 1 deletion YamlDotNet.Test/Core/ParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,8 @@ public void CommentsAreReturnedWhenRequested()
# Bottom comment
"), skipComments: false)),
StreamStart,
StandaloneComment("Top comment"),
DocumentStart(Implicit),
StandaloneComment("Top comment"),
BlockSequenceStart,
PlainScalar("first"),
InlineComment("Comment on first item"),
Expand Down
41 changes: 41 additions & 0 deletions YamlDotNet.Test/Serialization/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1302,5 +1302,46 @@ public void AttributeOverridesAndNamingConventionDoNotConflict()
var deserializedFoo = deserializer.Deserialize<Foo>(yaml);
Assert.True(deserializedFoo.IsRequired);
}

[Fact]
public void YamlConvertiblesAreAbleToEmitAndParseComments()
{
var serializer = new Serializer();
var yaml = serializer.Serialize(new CommentWrapper<string> { Comment = "A comment", Value = "The value" });

var deserializer = new Deserializer();
var parser = new Parser(new Scanner(new StringReader(yaml), skipComments: false));
var parsed = deserializer.Deserialize<CommentWrapper<string>>(parser);

Assert.Equal("A comment", parsed.Comment);
Assert.Equal("The value", parsed.Value);
}

public class CommentWrapper<T> : IYamlConvertible
{
public string Comment { get; set; }
public T Value { get; set; }

public void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer)
{
var comment = parser.Allow<Comment>();
if (comment != null)
{
Comment = comment.Value;
}

Value = (T)nestedObjectDeserializer(typeof(T));
}

public void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
{
if (!string.IsNullOrEmpty(Comment))
{
emitter.Emit(new Comment(Comment, false));
}

nestedObjectSerializer(Value, typeof(T));
}
}
}
}
3 changes: 2 additions & 1 deletion YamlDotNet/Core/Emitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -648,11 +648,12 @@ private void EmitComment(Comment comment)
}
else
{
WriteBreak();
WriteIndent();
}

Write("# ");
Write(comment.Value);
WriteBreak();

isIndentation = true;
}
Expand Down
40 changes: 39 additions & 1 deletion YamlDotNet/Core/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public ParsingEvent Current
}
}

private readonly Queue<Events.ParsingEvent> pendingEvents = new Queue<Events.ParsingEvent>();
private readonly EventQueue pendingEvents = new EventQueue();

/// <summary>
/// Moves to the next event.
Expand Down Expand Up @@ -946,5 +946,43 @@ private ParsingEvent ParseFlowMappingValue(bool isEmpty)
state = ParserState.FlowMappingKey;
return ProcessEmptyScalar(GetCurrentToken().Start);
}

private class EventQueue
{
// This class is specialized for our specific use case where there are exactly two priority levels.
// If more levels are required, a more generic implementation should be used instead.
private readonly Queue<ParsingEvent> highPriorityEvents = new Queue<ParsingEvent>();
private readonly Queue<ParsingEvent> normalPriorityEvents = new Queue<ParsingEvent>();

public void Enqueue(ParsingEvent @event)
{
switch (@event.Type)
{
case Events.EventType.StreamStart:
case Events.EventType.DocumentStart:
highPriorityEvents.Enqueue(@event);
break;

default:
normalPriorityEvents.Enqueue(@event);
break;
}
}

public ParsingEvent Dequeue()
{
return highPriorityEvents.Count > 0
? highPriorityEvents.Dequeue()
: normalPriorityEvents.Dequeue();
}

public int Count
{
get
{
return highPriorityEvents.Count + normalPriorityEvents.Count;
}
}
}
}
}

0 comments on commit a662fe5

Please sign in to comment.