From 1c9abc8fa4702c06d53b866dd2e7ca3b9c865f7e Mon Sep 17 00:00:00 2001 From: Chen Date: Fri, 24 Jul 2020 20:28:40 +0800 Subject: [PATCH] fix issue743: handle the empty content of flow sep/map correctly during emitting. (#921) * fix issue743: handle the empty content of flow sep/map correctly during emitting. * handle the empty Tag/Anchor properly. * delete comment --- src/emitter.cpp | 14 ++++++- src/emitterstate.cpp | 7 ++++ test/integration/emitter_test.cpp | 70 +++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/src/emitter.cpp b/src/emitter.cpp index ba52a38..251df8c 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -205,6 +205,7 @@ void Emitter::EmitBeginSeq() { void Emitter::EmitEndSeq() { if (!good()) return; + FlowType::value originalType = m_pState->CurGroupFlowType(); if (m_pState->CurGroupChildCount() == 0) m_pState->ForceFlow(); @@ -213,8 +214,12 @@ void Emitter::EmitEndSeq() { if (m_stream.comment()) m_stream << "\n"; m_stream << IndentTo(m_pState->CurIndent()); - if (m_pState->CurGroupChildCount() == 0) + if (originalType == FlowType::Block) { m_stream << "["; + } else { + if (m_pState->CurGroupChildCount() == 0 && !m_pState->HasBegunNode()) + m_stream << "["; + } m_stream << "]"; } @@ -235,6 +240,7 @@ void Emitter::EmitBeginMap() { void Emitter::EmitEndMap() { if (!good()) return; + FlowType::value originalType = m_pState->CurGroupFlowType(); if (m_pState->CurGroupChildCount() == 0) m_pState->ForceFlow(); @@ -243,8 +249,12 @@ void Emitter::EmitEndMap() { if (m_stream.comment()) m_stream << "\n"; m_stream << IndentTo(m_pState->CurIndent()); - if (m_pState->CurGroupChildCount() == 0) + if (originalType == FlowType::Block) { m_stream << "{"; + } else { + if (m_pState->CurGroupChildCount() == 0 && !m_pState->HasBegunNode()) + m_stream << "{"; + } m_stream << "}"; } diff --git a/src/emitterstate.cpp b/src/emitterstate.cpp index 70f937d..e734481 100644 --- a/src/emitterstate.cpp +++ b/src/emitterstate.cpp @@ -160,6 +160,13 @@ void EmitterState::EndedGroup(GroupType::value type) { return SetError(ErrorMsg::UNEXPECTED_END_MAP); } + if (m_hasTag) { + SetError(ErrorMsg::INVALID_TAG); + } + if (m_hasAnchor) { + SetError(ErrorMsg::INVALID_ANCHOR); + } + // get rid of the current group { std::unique_ptr pFinishedGroup = std::move(m_groups.back()); diff --git a/test/integration/emitter_test.cpp b/test/integration/emitter_test.cpp index 86eeb60..c79ade4 100644 --- a/test/integration/emitter_test.cpp +++ b/test/integration/emitter_test.cpp @@ -138,6 +138,56 @@ TEST_F(EmitterTest, EmptyFlowSeq) { ExpectEmit("[]"); } +TEST_F(EmitterTest, EmptyBlockSeqWithBegunContent) { + out << BeginSeq; + out << BeginSeq << Comment("comment") << EndSeq; + out << BeginSeq << Newline << EndSeq; + out << EndSeq; + + ExpectEmit(R"(- +# comment + [] +- + + [])"); +} + +TEST_F(EmitterTest, EmptyBlockMapWithBegunContent) { + out << BeginSeq; + out << BeginMap << Comment("comment") << EndMap; + out << BeginMap << Newline << EndMap; + out << EndSeq; + + ExpectEmit(R"(- # comment + {} +- + {})"); +} + +TEST_F(EmitterTest, EmptyFlowSeqWithBegunContent) { + out << Flow; + out << BeginSeq; + out << BeginSeq << Comment("comment") << EndSeq; + out << BeginSeq << Newline << EndSeq; + out << EndSeq; + + ExpectEmit(R"([[ # comment + ], [ + ]])"); +} + +TEST_F(EmitterTest, EmptyFlowMapWithBegunContent) { + out << Flow; + out << BeginSeq; + out << BeginMap << Comment("comment") << EndMap; + out << BeginMap << Newline << EndMap; + out << EndSeq; + + ExpectEmit(R"([{ # comment + }, { + }])"); +} + TEST_F(EmitterTest, NestedBlockSeq) { out << BeginSeq; out << "item 1"; @@ -1553,6 +1603,26 @@ TEST_F(EmitterErrorTest, BadLocalTag) { ExpectEmitError("invalid tag"); } +TEST_F(EmitterErrorTest, BadTagAndTag) { + out << VerbatimTag("!far") << VerbatimTag("!foo") << "bar"; + ExpectEmitError(ErrorMsg::INVALID_TAG); +} + +TEST_F(EmitterErrorTest, BadAnchorAndAnchor) { + out << Anchor("far") << Anchor("foo") << "bar"; + ExpectEmitError(ErrorMsg::INVALID_ANCHOR); +} + +TEST_F(EmitterErrorTest, BadEmptyAnchorOnGroup) { + out << BeginSeq << "bar" << Anchor("foo") << EndSeq; + ExpectEmitError(ErrorMsg::INVALID_ANCHOR); +} + +TEST_F(EmitterErrorTest, BadEmptyTagOnGroup) { + out << BeginSeq << "bar" << VerbatimTag("!foo") << EndSeq; + ExpectEmitError(ErrorMsg::INVALID_TAG); +} + TEST_F(EmitterErrorTest, ExtraEndSeq) { out << BeginSeq; out << "Hello";