blob: 8e80fd2a04b557ac01f23f82a92ac7bee5ee53eb [file] [log] [blame]
// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "common/formatting/format_token.h"
#include <sstream>
#include <string>
#include <vector>
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
#include "common/formatting/unwrapped_line.h"
#include "common/formatting/unwrapped_line_test_utils.h"
#include "common/text/token_info.h"
#include "common/util/range.h"
namespace verible {
namespace {
// Tests the string representation of the SpacingOptions enum.
TEST(BreakDecisionTest, StringRep) {
{
std::ostringstream stream;
stream << SpacingOptions::Undecided;
EXPECT_EQ(stream.str(), "undecided");
}
{
std::ostringstream stream;
stream << SpacingOptions::MustAppend;
EXPECT_EQ(stream.str(), "must-append");
}
{
std::ostringstream stream;
stream << SpacingOptions::MustWrap;
EXPECT_EQ(stream.str(), "must-wrap");
}
{
std::ostringstream stream;
stream << SpacingOptions::Preserve;
EXPECT_EQ(stream.str(), "preserve");
}
{
std::ostringstream stream;
stream << SpacingOptions::AppendAligned;
EXPECT_EQ(stream.str(), "append-aligned");
}
}
// Tests the string representation of the GroupBalancing enum.
TEST(GroupBalancingTest, StringRep) {
{
std::ostringstream stream;
stream << GroupBalancing::None;
EXPECT_EQ(stream.str(), "none");
}
{
std::ostringstream stream;
stream << GroupBalancing::Open;
EXPECT_EQ(stream.str(), "open");
}
{
std::ostringstream stream;
stream << GroupBalancing::Close;
EXPECT_EQ(stream.str(), "close");
}
}
// Test that InterTokenInfo initializes to reasonable values.
TEST(InterTokenInfoTest, Initialization) {
InterTokenInfo info;
EXPECT_EQ(0, info.spaces_required);
EXPECT_EQ(0, info.break_penalty);
EXPECT_EQ(info.break_decision, SpacingOptions::Undecided);
}
// Test for InterTokenInfo equality.
TEST(InterTokenInfoTest, Equality) {
InterTokenInfo info1, info2;
EXPECT_EQ(info1, info1);
EXPECT_EQ(info1, info2);
}
// Test for InterTokenInfo inequality.
TEST(InterTokenInfoTest, Inequality) {
InterTokenInfo info1;
{
InterTokenInfo info2;
info2.spaces_required = 66;
EXPECT_NE(info1, info2);
}
{
InterTokenInfo info3;
info3.break_penalty = 44;
EXPECT_NE(info1, info3);
}
{
InterTokenInfo info4;
info4.break_decision = SpacingOptions::MustAppend;
EXPECT_NE(info1, info4);
}
{
InterTokenInfo info5;
info5.break_decision = SpacingOptions::MustWrap;
EXPECT_NE(info1, info5);
}
}
// Test that PreFormatToken initializes correctly.
TEST(PreFormatTokenTest, DefaultCtor) {
PreFormatToken ftoken;
EXPECT_EQ(ftoken.token, nullptr);
}
// Test that vector of PreFormatToken is resizable.
TEST(PreFormatTokenTest, VectorResizeable) {
std::vector<PreFormatToken> ftokens;
ftokens.resize(4);
EXPECT_EQ(ftokens.size(), 4);
}
TEST(PreFormatTokenTest, OriginalLeadingSpaces) {
const absl::string_view text("abcdefgh");
const TokenInfo tok1(1, text.substr(1, 3)), tok2(2, text.substr(5, 2));
{
PreFormatToken p1(&tok1), p2(&tok2);
// original spacing not set
EXPECT_TRUE(p1.OriginalLeadingSpaces().empty());
EXPECT_TRUE(p2.OriginalLeadingSpaces().empty());
}
{
PreFormatToken p1(&tok1), p2(&tok2);
// set original spacing
p1.before.preserved_space_start = text.begin();
p2.before.preserved_space_start = tok1.text().end();
EXPECT_TRUE(BoundsEqual(p1.OriginalLeadingSpaces(), text.substr(0, 1)));
EXPECT_TRUE(BoundsEqual(p2.OriginalLeadingSpaces(), text.substr(4, 1)));
}
}
TEST(PreFormatTokenTest, ExcessSpacesNoNewline) {
const absl::string_view text("abcdefgh");
const TokenInfo tok(1, text.substr(1, 3));
PreFormatToken p(&tok); // before.preserved_space_start == nullptr
EXPECT_EQ(p.ExcessSpaces(), 0);
p.before.preserved_space_start = text.begin();
p.before.spaces_required = 0;
EXPECT_EQ(p.ExcessSpaces(), 1);
p.before.spaces_required = 2;
EXPECT_EQ(p.ExcessSpaces(), -1);
}
TEST(PreFormatTokenTest, ExcessSpacesNewline) {
const absl::string_view text("\nbcdefgh");
const TokenInfo tok(1, text.substr(1, 3));
PreFormatToken p(&tok); // before.preserved_space_start == nullptr
EXPECT_EQ(p.ExcessSpaces(), 0);
p.before.preserved_space_start = text.begin();
p.before.spaces_required = 0;
EXPECT_EQ(p.ExcessSpaces(), 0);
p.before.spaces_required = 2;
EXPECT_EQ(p.ExcessSpaces(), 0);
}
TEST(PreFormatTokenTest, LeadingSpacesLength) {
const absl::string_view text("abcdefgh");
const TokenInfo tok1(1, text.substr(1, 3)), tok2(2, text.substr(5, 2));
{
PreFormatToken p1(&tok1), p2(&tok2);
p1.before.spaces_required = 0;
p2.before.spaces_required = 3;
// original spacing not set
EXPECT_EQ(p1.LeadingSpacesLength(), 0);
EXPECT_EQ(p2.LeadingSpacesLength(), 3);
}
{
PreFormatToken p1(&tok1), p2(&tok2);
// set original spacing, but not preserve mode.
p1.before.preserved_space_start = text.begin();
p1.before.break_decision = SpacingOptions::Undecided;
p1.before.spaces_required = 1;
p2.before.preserved_space_start = tok1.text().end();
p2.before.break_decision = SpacingOptions::Undecided;
p2.before.spaces_required = 2;
EXPECT_EQ(p1.LeadingSpacesLength(), 1);
EXPECT_EQ(p2.LeadingSpacesLength(), 2);
}
{
PreFormatToken p1(&tok1), p2(&tok2);
// set original spacing and preserve mode.
p1.before.preserved_space_start = text.begin();
p1.before.break_decision = SpacingOptions::Preserve;
p1.before.spaces_required = 2;
p2.before.preserved_space_start = tok1.text().end();
p2.before.break_decision = SpacingOptions::Preserve;
p2.before.spaces_required = 4;
EXPECT_EQ(p1.LeadingSpacesLength(), 1); // "a"
EXPECT_EQ(p2.LeadingSpacesLength(), 1); // "d"
}
}
class ConnectPreFormatTokensPreservedSpaceStartsTest
: public ::testing::Test,
public UnwrappedLineMemoryHandler {};
TEST_F(ConnectPreFormatTokensPreservedSpaceStartsTest, Empty) {
constexpr absl::string_view text("");
CreateTokenInfosExternalStringBuffer({});
ConnectPreFormatTokensPreservedSpaceStarts(text.begin(), &pre_format_tokens_);
EXPECT_TRUE(pre_format_tokens_.empty());
}
TEST_F(ConnectPreFormatTokensPreservedSpaceStartsTest, OneToken) {
constexpr absl::string_view text("xyz");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(0, 3)},
});
ConnectPreFormatTokensPreservedSpaceStarts(text.begin(), &pre_format_tokens_);
EXPECT_TRUE(BoundsEqual(pre_format_tokens_.front().OriginalLeadingSpaces(),
text.substr(0, 0)));
}
TEST_F(ConnectPreFormatTokensPreservedSpaceStartsTest, OneTokenLeadingSpace) {
constexpr absl::string_view text(" xyz");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(2, 3)}, // "xyz"
});
ConnectPreFormatTokensPreservedSpaceStarts(text.begin(), &pre_format_tokens_);
EXPECT_TRUE(BoundsEqual(pre_format_tokens_.front().OriginalLeadingSpaces(),
text.substr(0, 2))); // " "
}
TEST_F(ConnectPreFormatTokensPreservedSpaceStartsTest, MultipleTokens) {
constexpr absl::string_view text(" xyz\t\t\nabc");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(2, 3)}, // "xyz"
{2, text.substr(8, 3)}, // "abc"
});
ConnectPreFormatTokensPreservedSpaceStarts(text.begin(), &pre_format_tokens_);
EXPECT_TRUE(BoundsEqual(pre_format_tokens_.front().OriginalLeadingSpaces(),
text.substr(0, 2))); // " "
EXPECT_TRUE(BoundsEqual(pre_format_tokens_.back().OriginalLeadingSpaces(),
text.substr(5, 3))); // "\t\t\n"
}
class PreserveSpacesOnDisabledTokenRangesTest
: public ::testing::Test,
public UnwrappedLineMemoryHandler {};
TEST_F(PreserveSpacesOnDisabledTokenRangesTest, DisableNone) {
constexpr absl::string_view text("a b c d e");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(0, 1)},
{2, text.substr(2, 1)},
{1, text.substr(4, 1)},
{3, text.substr(6, 1)},
{2, text.substr(8, 1)},
});
ByteOffsetSet disabled_bytes; // empty
PreserveSpacesOnDisabledTokenRanges(&pre_format_tokens_, disabled_bytes,
text);
for (const auto& ftoken : pre_format_tokens_) {
EXPECT_EQ(ftoken.before.break_decision, SpacingOptions::Undecided);
}
}
TEST_F(PreserveSpacesOnDisabledTokenRangesTest, DisableSpaceBeforeText) {
constexpr absl::string_view text("a b c d e");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(0, 1)},
{2, text.substr(2, 1)},
{1, text.substr(4, 1)},
{3, text.substr(6, 1)},
{2, text.substr(8, 1)},
});
ByteOffsetSet disabled_bytes{{5, 7}}; // substring " d"
PreserveSpacesOnDisabledTokenRanges(&pre_format_tokens_, disabled_bytes,
text);
const auto& ftokens = pre_format_tokens_;
EXPECT_EQ(ftokens[0].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(ftokens[1].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(ftokens[2].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(ftokens[3].before.break_decision,
SpacingOptions::Preserve); // before "d"
EXPECT_EQ(ftokens[4].before.break_decision, SpacingOptions::Undecided);
}
TEST_F(PreserveSpacesOnDisabledTokenRangesTest, DisableSpaceAfterText) {
constexpr absl::string_view text("a b c d e");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(0, 1)},
{2, text.substr(2, 1)},
{1, text.substr(4, 1)},
{3, text.substr(6, 1)},
{2, text.substr(8, 1)},
});
ByteOffsetSet disabled_bytes{{4, 6}}; // substring "c "
PreserveSpacesOnDisabledTokenRanges(&pre_format_tokens_, disabled_bytes,
text);
const auto& ftokens = pre_format_tokens_;
EXPECT_EQ(ftokens[0].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(ftokens[1].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(ftokens[2].before.break_decision, SpacingOptions::Preserve); // "c"
EXPECT_EQ(ftokens[3].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(ftokens[4].before.break_decision, SpacingOptions::Undecided);
}
TEST_F(PreserveSpacesOnDisabledTokenRangesTest, DisableSpanningTwoTokens) {
constexpr absl::string_view text("a b c d e");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(0, 1)},
{2, text.substr(2, 1)},
{1, text.substr(4, 1)},
{3, text.substr(6, 1)},
{2, text.substr(8, 1)},
});
ByteOffsetSet disabled_bytes{{4, 7}}; // substring "c d"
PreserveSpacesOnDisabledTokenRanges(&pre_format_tokens_, disabled_bytes,
text);
const auto& ftokens = pre_format_tokens_;
EXPECT_EQ(ftokens[0].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(ftokens[1].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(ftokens[2].before.break_decision,
SpacingOptions::Preserve); // before "c"
EXPECT_EQ(ftokens[3].before.break_decision, SpacingOptions::Preserve);
EXPECT_EQ(ftokens[4].before.break_decision, SpacingOptions::Undecided);
}
TEST_F(PreserveSpacesOnDisabledTokenRangesTest, DisableSpanningMustWrap) {
constexpr absl::string_view text("a b c d e");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(0, 1)},
{2, text.substr(2, 1)},
{1, text.substr(4, 1)},
{3, text.substr(6, 1)},
{2, text.substr(8, 1)},
});
ConnectPreFormatTokensPreservedSpaceStarts(text.begin(), &pre_format_tokens_);
ByteOffsetSet disabled_bytes{{2, 5}}; // substring "b c"
pre_format_tokens_[2].before.break_decision = SpacingOptions::MustWrap;
PreserveSpacesOnDisabledTokenRanges(&pre_format_tokens_, disabled_bytes,
text);
const auto& ftokens = pre_format_tokens_;
EXPECT_EQ(ftokens[0].before.break_decision, SpacingOptions::Undecided);
EXPECT_TRUE(
BoundsEqual(ftokens[0].OriginalLeadingSpaces(), text.substr(0, 0)));
EXPECT_EQ(ftokens[1].before.break_decision, SpacingOptions::Preserve);
EXPECT_TRUE(
BoundsEqual(ftokens[1].OriginalLeadingSpaces(), text.substr(1, 1)));
EXPECT_EQ(ftokens[2].before.break_decision, SpacingOptions::Preserve);
EXPECT_TRUE(
BoundsEqual(ftokens[2].OriginalLeadingSpaces(), text.substr(3, 1)));
EXPECT_EQ(ftokens[3].before.break_decision, SpacingOptions::Undecided);
EXPECT_TRUE(
BoundsEqual(ftokens[3].OriginalLeadingSpaces(), text.substr(5, 1)));
EXPECT_EQ(ftokens[4].before.break_decision, SpacingOptions::Undecided);
EXPECT_TRUE(
BoundsEqual(ftokens[4].OriginalLeadingSpaces(), text.substr(7, 1)));
}
TEST_F(PreserveSpacesOnDisabledTokenRangesTest,
DisableSpanningMustWrapWithNewline) {
constexpr absl::string_view text("a\nb\nc d e");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(0, 1)},
{2, text.substr(2, 1)},
{1, text.substr(4, 1)},
{3, text.substr(6, 1)},
{2, text.substr(8, 1)},
});
ConnectPreFormatTokensPreservedSpaceStarts(text.begin(), &pre_format_tokens_);
ByteOffsetSet disabled_bytes{{2, 5}}; // substring "b\nc"
pre_format_tokens_[1].before.break_decision = SpacingOptions::MustWrap;
PreserveSpacesOnDisabledTokenRanges(&pre_format_tokens_, disabled_bytes,
text);
const auto& ftokens = pre_format_tokens_;
auto indices = [&text](const absl::string_view& range) {
return SubRangeIndices(range, text);
};
EXPECT_EQ(ftokens[0].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(indices(ftokens[0].OriginalLeadingSpaces()),
indices(text.substr(0, 0)));
EXPECT_EQ(ftokens[1].before.break_decision, SpacingOptions::Preserve);
EXPECT_EQ( // \n was consumed
indices(ftokens[1].OriginalLeadingSpaces()), indices(text.substr(2, 0)));
EXPECT_EQ(ftokens[2].before.break_decision, SpacingOptions::Preserve);
EXPECT_EQ(indices(ftokens[2].OriginalLeadingSpaces()),
indices(text.substr(3, 1)));
EXPECT_EQ(ftokens[3].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(indices(ftokens[3].OriginalLeadingSpaces()),
indices(text.substr(5, 1)));
EXPECT_EQ(ftokens[4].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(indices(ftokens[4].OriginalLeadingSpaces()),
indices(text.substr(7, 1)));
}
TEST_F(PreserveSpacesOnDisabledTokenRangesTest,
DisableSpanningMustWrapWithNewlineKeepIndentation) {
constexpr absl::string_view text("a\n b\n c d e");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(0, 1)},
{2, text.substr(4, 1)},
{1, text.substr(8, 1)},
{3, text.substr(10, 1)},
{2, text.substr(12, 1)},
});
ConnectPreFormatTokensPreservedSpaceStarts(text.begin(), &pre_format_tokens_);
ByteOffsetSet disabled_bytes{{4, 9}}; // substring "b\n c"
pre_format_tokens_[1].before.break_decision = SpacingOptions::MustWrap;
PreserveSpacesOnDisabledTokenRanges(&pre_format_tokens_, disabled_bytes,
text);
const auto& ftokens = pre_format_tokens_;
auto indices = [&text](const absl::string_view& range) {
return SubRangeIndices(range, text);
};
EXPECT_EQ(ftokens[0].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(indices(ftokens[0].OriginalLeadingSpaces()),
indices(text.substr(0, 0)));
EXPECT_EQ(ftokens[1].before.break_decision, SpacingOptions::Preserve);
EXPECT_EQ( // \n was consumed, " " remains
indices(ftokens[1].OriginalLeadingSpaces()), indices(text.substr(2, 2)));
EXPECT_EQ(ftokens[2].before.break_decision, SpacingOptions::Preserve);
EXPECT_EQ(indices(ftokens[2].OriginalLeadingSpaces()),
indices(text.substr(5, 3)));
EXPECT_EQ(ftokens[3].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(indices(ftokens[3].OriginalLeadingSpaces()),
indices(text.substr(9, 1)));
EXPECT_EQ(ftokens[4].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(indices(ftokens[4].OriginalLeadingSpaces()),
indices(text.substr(11, 1)));
}
TEST_F(PreserveSpacesOnDisabledTokenRangesTest, MultipleOffsetRanges) {
constexpr absl::string_view text("a\nb\nc d e ff gg");
CreateTokenInfosExternalStringBuffer({
{1, text.substr(0, 1)},
{2, text.substr(2, 1)},
{1, text.substr(4, 1)},
{3, text.substr(6, 1)},
{2, text.substr(8, 1)},
{2, text.substr(10, 2)},
{2, text.substr(13, 2)},
});
ConnectPreFormatTokensPreservedSpaceStarts(text.begin(), &pre_format_tokens_);
ByteOffsetSet disabled_bytes{{2, 5}, {8, 12}}; // substrings "b\nc", "e ff"
pre_format_tokens_[1].before.break_decision = SpacingOptions::MustWrap;
PreserveSpacesOnDisabledTokenRanges(&pre_format_tokens_, disabled_bytes,
text);
const auto& ftokens = pre_format_tokens_;
auto indices = [&text](const absl::string_view& range) {
return SubRangeIndices(range, text);
};
EXPECT_EQ(ftokens[0].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(indices(ftokens[0].OriginalLeadingSpaces()),
indices(text.substr(0, 0)));
EXPECT_EQ(ftokens[1].before.break_decision, SpacingOptions::Preserve);
EXPECT_EQ( // \n was consumed
indices(ftokens[1].OriginalLeadingSpaces()), indices(text.substr(2, 0)));
EXPECT_EQ(ftokens[2].before.break_decision, SpacingOptions::Preserve);
EXPECT_EQ(indices(ftokens[2].OriginalLeadingSpaces()),
indices(text.substr(3, 1)));
EXPECT_EQ(ftokens[3].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(indices(ftokens[3].OriginalLeadingSpaces()),
indices(text.substr(5, 1)));
EXPECT_EQ(ftokens[4].before.break_decision, SpacingOptions::Preserve);
EXPECT_EQ(indices(ftokens[4].OriginalLeadingSpaces()),
indices(text.substr(7, 1)));
EXPECT_EQ(ftokens[5].before.break_decision, SpacingOptions::Preserve);
EXPECT_EQ(indices(ftokens[5].OriginalLeadingSpaces()),
indices(text.substr(9, 1)));
EXPECT_EQ(ftokens[6].before.break_decision, SpacingOptions::Undecided);
EXPECT_EQ(indices(ftokens[6].OriginalLeadingSpaces()),
indices(text.substr(12, 1)));
}
// Test that FormattedText prints correctly.
TEST(FormattedTokenTest, FormattedText) {
TokenInfo token(0, "roobar");
PreFormatToken ptoken(&token);
{
FormattedToken ftoken(ptoken);
std::ostringstream stream;
stream << ftoken;
EXPECT_EQ("roobar", stream.str());
}
{
FormattedToken ftoken(ptoken);
ftoken.before.spaces = 3;
std::ostringstream stream;
stream << ftoken;
EXPECT_EQ(" roobar", stream.str());
}
{
FormattedToken ftoken(ptoken);
ftoken.before.action = SpacingDecision::Wrap;
std::ostringstream stream;
stream << ftoken;
EXPECT_EQ("\nroobar", stream.str());
}
{
FormattedToken ftoken(ptoken);
ftoken.before.action = SpacingDecision::Wrap;
ftoken.before.spaces = 2;
std::ostringstream stream;
stream << ftoken;
EXPECT_EQ("\n roobar", stream.str());
}
}
TEST(FormattedTokenTest, OriginalLeadingSpaces) {
const absl::string_view text("abcdefgh");
const TokenInfo tok1(1, text.substr(1, 3)), tok2(2, text.substr(5, 2));
const PreFormatToken p1(&tok1), p2(&tok2);
{
FormattedToken ft1(p1), ft2(p2);
// original spacing not set
EXPECT_TRUE(ft1.OriginalLeadingSpaces().empty());
EXPECT_TRUE(ft2.OriginalLeadingSpaces().empty());
}
{
FormattedToken ft1(p1), ft2(p2);
// set original spacing
ft1.before.preserved_space_start = text.begin();
ft2.before.preserved_space_start = tok1.text().end();
EXPECT_TRUE(BoundsEqual(ft1.OriginalLeadingSpaces(), text.substr(0, 1)));
EXPECT_TRUE(BoundsEqual(ft2.OriginalLeadingSpaces(), text.substr(4, 1)));
}
}
TEST(FormattedTokenTest, PreservedSpaces) {
const absl::string_view text("abcdefgh");
const TokenInfo tok1(1, text.substr(1, 3)), tok2(2, text.substr(5, 2));
const PreFormatToken p1(&tok1), p2(&tok2);
{
FormattedToken ft1(p1), ft2(p2);
ft1.before.spaces = 2;
ft2.before.spaces = 3;
std::ostringstream stream;
stream << ft1 << ft2;
EXPECT_EQ(stream.str(), " bcd fg");
}
{
FormattedToken ft1(p1), ft2(p2);
ft1.before.spaces = 2; // ignored
ft1.before.action = SpacingDecision::Preserve;
ft2.before.spaces = 3; // ignored
ft2.before.action = SpacingDecision::Preserve;
// preserved_space_start takes precedence over the other attributes
ft1.before.preserved_space_start = text.begin();
ft2.before.preserved_space_start = tok1.text().end();
std::ostringstream stream;
stream << ft1 << ft2;
// For testing purposes, it doesn't matter what text was in the gap between
// the tokens, need not be space.
EXPECT_EQ(stream.str(), "abcdefg");
}
}
// Test for InterTokenInfo string representation.
TEST(InterTokenInfoTest, StringRep) {
std::ostringstream stream;
InterTokenInfo info;
stream << info;
EXPECT_EQ(
R"str({
spaces_required: 0
break_penalty: 0
break_decision: undecided
preserve_space?: 0
})str",
stream.str());
}
TEST(InterTokenInfoTest, CompactNotationUndecided) {
std::ostringstream stream;
InterTokenInfo info;
info.break_decision = SpacingOptions::Undecided;
info.spaces_required = 3;
info.break_penalty = 25;
info.CompactNotation(stream);
EXPECT_EQ(stream.str(), "<_3,25>");
}
TEST(InterTokenInfoTest, CompactNotationMustAppend) {
std::ostringstream stream;
InterTokenInfo info;
info.break_decision = SpacingOptions::MustAppend;
info.spaces_required = 2;
info.CompactNotation(stream);
EXPECT_EQ(stream.str(), "<+_2>");
}
TEST(InterTokenInfoTest, CompactNotationMustWrap) {
std::ostringstream stream;
InterTokenInfo info;
info.break_decision = SpacingOptions::MustWrap;
info.CompactNotation(stream);
EXPECT_EQ(stream.str(), "<\\n>");
}
TEST(InterTokenInfoTest, CompactNotationAppendAligned) {
std::ostringstream stream;
InterTokenInfo info;
info.break_decision = SpacingOptions::AppendAligned;
info.spaces_required = 3;
info.CompactNotation(stream);
EXPECT_EQ(stream.str(), "<|_3>");
}
TEST(InterTokenInfoTest, CompactNotationPreserve) {
std::ostringstream stream;
InterTokenInfo info;
info.break_decision = SpacingOptions::Preserve;
info.CompactNotation(stream);
EXPECT_EQ(stream.str(), "<pre>");
}
// Test that Length() returns the correct distance between L and R location of
// an Empty TokenInfo
TEST(PreFormatTokenTest, FormatTokenLengthEmptyTest) {
// Empty
TokenInfo empty_token_info(0, "");
PreFormatToken empty_format_token(&empty_token_info);
EXPECT_EQ(0, empty_format_token.Length());
}
// Test that Length() returns the correct distance between L and R location of
// TokenInfo
TEST(PreFormatTokenTest, FormatTokenLengthTest) {
// Valid Location
TokenInfo token_info(1, "Hello World!");
PreFormatToken format_token(&token_info);
EXPECT_EQ(12, format_token.Length());
}
// Test for PreFormatToken's string representation.
TEST(PreFormatTokenTest, StringRep) {
TokenInfo token_info(1, "Hello");
PreFormatToken format_token(&token_info);
std::string str(format_token.ToString());
absl::string_view strv(str);
EXPECT_NE(strv.find("TokenInfo:"), strv.npos);
EXPECT_NE(strv.find("before:"), strv.npos);
EXPECT_NE(strv.find("break_decision:"), strv.npos);
}
} // namespace
} // namespace verible