| Index: unittests/Bitcode/NaClTextFormatterTest.cpp
|
| diff --git a/unittests/Bitcode/NaClTextFormatterTest.cpp b/unittests/Bitcode/NaClTextFormatterTest.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..656ba8e283b60d937ad834fdd12740dfd1338e29
|
| --- /dev/null
|
| +++ b/unittests/Bitcode/NaClTextFormatterTest.cpp
|
| @@ -0,0 +1,1410 @@
|
| +//===- llvm/unittest/Bitcode/NaClTextFormatterTest.cpp --------------------===//
|
| +// Tests the text formatter for PNaCl bitcode.
|
| +//
|
| +// The LLVM Compiler Infrastructure
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +// Tests if the text formatter for PNaCl bitcode works as expected.
|
| +
|
| +#include "llvm/ADT/STLExtras.h"
|
| +#include "llvm/Bitcode/NaCl/NaClObjDumpStream.h"
|
| +
|
| +#include "gtest/gtest.h"
|
| +
|
| +#include <iostream>
|
| +
|
| +using namespace llvm;
|
| +using namespace llvm::naclbitc;
|
| +
|
| +namespace {
|
| +
|
| +/// Simple test harness for testing a text formatter. This class takes
|
| +/// an array of tokens, parses it, and then uses the text formatter to
|
| +/// format it. To test the features of the text formatter, the parser
|
| +/// detects function calls, and inserts appropriate open/close
|
| +/// parenthesis directives, as well as clustering directives.
|
| +///
|
| +/// For clustering, we consider each argument, as well as the entire
|
| +/// function. In case the entire function can't be printed, we add two
|
| +/// additional clusters as backup strategies:
|
| +///
|
| +/// 1) Cluster the called function with it's first argument.
|
| +/// 2) Cluster the called function with the open parenthesis.
|
| +///
|
| +/// These rules can be formalized as the following cases, where:
|
| +/// '<' denotes a StartCluster.
|
| +/// '>' denotes a FinishCluster.
|
| +/// '[' represents a regular expression open parenthesis.
|
| +/// ']' represents a regular expression close parenthesis.
|
| +/// '*' denotes regular expression repeat operation.
|
| +///
|
| +/// The cases to consider are:
|
| +///
|
| +/// case 1: <<<f(>)>>
|
| +/// case 2: <<<f(><x>)>>
|
| +/// case 3: <<<f(><x,>>[<y,>]*<z>)>
|
| +///
|
| +/// Note: In cases 1 and 2, there is an unnecessary pair of clustering
|
| +/// directives. This is intentional. It has been added so that the
|
| +/// parser need not build an AST before formatting. Also note that
|
| +/// case 3 covers all function calls with 2 or more arguments.
|
| +class FormatterTester {
|
| +private:
|
| + // Defines states of the token parser, as it looks for function calls.
|
| + // These states are used to determine where (and when) clustering
|
| + // directives should be added to the Tokens() stream. If no
|
| + // transition applies for a state, the default transition is applied,
|
| + // which is to add the next token to the Tokens() stream.
|
| + //
|
| + // Note: We use '|' to denote the current position of the token parser.
|
| + //
|
| + // In all states, the following transition is possible (pushing the
|
| + // current state onto the parse stack), and is applied after state
|
| + // specific transitions (below):
|
| + //
|
| + // |<<<f(>)>> => StartingFcn: <<<|f(>)>>
|
| + // |<<<f(><x>)>> => StartingFcn: <<<|f(><x>)>>
|
| + // |<<<f(><x,>>[<y,>]*<z>)> => StartingFcn: <<<|f(><x,>>[<y,>]*<z>)>
|
| + //
|
| + // Note: We use the notation == to state that two expressions are equivalent.
|
| + // In particular,
|
| + //
|
| + // [x|]* == [|x]*
|
| + //
|
| + // since being at the end of a repeated instruction also means that
|
| + // you are at the beginning of the next (unrolled) repetition.
|
| + enum FormatterState {
|
| + LookingForFunction, // Start state
|
| +
|
| + StartingFcn,
|
| + // <<<f(|>)>> => BeforeFirstArg: <<<f(>|)>>
|
| + // <<<f(|><x>)>> => BeforeFirstArg: <<<f(>|<x>(>>
|
| + // <<<f(|><x,>>[<y,>]*<z>)> => BeforeFirstArg: <<<f(>|<x,>>[<y,>]*<z>)>
|
| +
|
| + BeforeFirstArg,
|
| + // <<<f(>|)>> => EndFcn2: <<<f(>|)>>
|
| + // <<<f(>|<x>)>> => InFirstArg: <<<f(><|x>)>>
|
| + // <<<f(>|<x,>>[<y,>]*<z>)> => InFirstArg <<<f(><|x,>>[<y,>]*<z>)>
|
| +
|
| + InFirstArg,
|
| + // <<<f(><x|>)>> => EndFcn2: <<<f(><x>|)>>
|
| + // <<<f(><x,|>>[<y,>]*<z>)> => BetweenArgs: <<<f(><x,>>[|<y,>]*<z>)>
|
| +
|
| + InOtherArg,
|
| + // <<<f(><x,>>[<y,|>]*<z>)> => BetweenArgs: <<<f(><x,>>[<y,>|]*<z>)>
|
| + // == <<<f(><x,>>[|<y,>]*<z>)>
|
| + // => BetweenArgs: <<<f(><x,>>[<y,>]*|<z>)>
|
| + // <<<f(><x,>>[<y,>]*<z|>)> => EndFcn1: <<<f(><x,>>[<y,>]*<z>|)>
|
| +
|
| + BetweenArgs,
|
| + // <<<f(><x,>>[|<y,>]*<z>)> => InOtherArg: <<<f(><x,>>[<|y,>]*<z>)>
|
| + // <<<f(><x,>>[<y,>]*|<z>)> => InOtherArg: <<<f(><x,>>[<y,>]*<|z>)>
|
| +
|
| + EndFcn2,
|
| + // <<<f(>)|>> => EndFcn1: <<<f(>)>|>
|
| + // <<<f(><x>)|>> => EndFcn1: <<<f(><x>)>|>
|
| +
|
| + EndFcn1
|
| + // <<<f(>)>|> => XXX: <<<f(>)>>|
|
| + // <<<f(><x>)>|> => XXX: <<<f(><x>)>>|
|
| + // <<<f(><x,>>[<y,>]*<z>)|> => XXX: <<<f(><x,>>[<y,>]*<z>)>|
|
| + //
|
| + // where XXX is the state popped from the parse stack.
|
| + };
|
| +
|
| +public:
|
| + FormatterTester(unsigned LineWidth)
|
| + : AddOpenCloseDirectives(false),
|
| + AddClusterDirectives(false),
|
| + Buffer(),
|
| + BufStream(Buffer),
|
| + Formatter(BufStream, LineWidth, " "),
|
| + CommaText(","),
|
| + SpaceText(" "),
|
| + OpenParenText("("),
|
| + CloseParenText(")"),
|
| + NewlineText("\n"),
|
| + Comma(&Formatter, CommaText),
|
| + Space(&Formatter, SpaceText),
|
| + OpenParen(&Formatter, OpenParenText),
|
| + CloseParen(&Formatter, CloseParenText),
|
| + StartCluster(&Formatter),
|
| + FinishCluster(&Formatter),
|
| + Tokenize(&Formatter),
|
| + Endline(&Formatter)
|
| + {
|
| + Reset();
|
| + Formatter.SetContinuationIndent(Formatter.GetIndent(2));
|
| + }
|
| +
|
| + /// Runs a test using the given sequence of tokens. If
|
| + /// AddOpenCloseDirectives is true, then "(" and ")" tokens
|
| + /// will change the local indent using the corresponding directives.
|
| + /// If AddClusterDirectives is true, then the clustering rules for
|
| + /// function calls will be applied.
|
| + std::string Test(const char *Tokens[], size_t NumTokens,
|
| + bool AddOpenCloseDirectives,
|
| + bool AddClusterDirectives,
|
| + unsigned Indent);
|
| +
|
| +private:
|
| + /// Reset the formatter for next test.
|
| + void Reset() {
|
| + BufStream.flush();
|
| + Buffer.clear();
|
| + State = LookingForFunction;
|
| + FunctionParseStack.clear();
|
| + }
|
| +
|
| + /// Collect the sequence of tokens, starting at Index, that
|
| + /// correspond to spaces, and return the number of spaces found.
|
| + unsigned CollectSpaces(size_t &Index,
|
| + const char *Tokens[],
|
| + size_t NumTokens) const {
|
| + unsigned Count = 0;
|
| + for (; Index < NumTokens; ++Index) {
|
| + std::string Token(Tokens[Index]);
|
| + if (Token != SpaceText) return Count;
|
| + ++Count;
|
| + }
|
| + return Count;
|
| + }
|
| +
|
| + /// Write out the given number of spaces using a space directive.
|
| + void WriteSpaces(unsigned Count) {
|
| + for (unsigned i = 0; i < Count; ++i) Formatter.Tokens() << Space;
|
| + }
|
| +
|
| + /// Insert clustering directives, based on the current state of the
|
| + /// parser. CurToken is the current (non-whitespace) token being
|
| + /// processed by the parser. NextToken is the next (non-whitespace)
|
| + /// token being processed. If BeforeCurrentToken, then the parser
|
| + /// is just before CurToken. Otherwise, it is just after NextToken.
|
| + ///
|
| + /// Note: When BeforeCurrentToken is false, it isn't necessarily
|
| + /// just before NextToken. This is because there may be space
|
| + /// (i.e. whitespace) tokens between CurToken and NextToken.
|
| + void InsertClusterDirectives(std::string &CurToken,
|
| + std::string &NextToken,
|
| + bool BeforeCurrentToken);
|
| +
|
| + /// Write out the given token. Implicitly uses corresponding directives
|
| + /// if applicable.
|
| + void WriteToken(const std::string &Token);
|
| +
|
| + // True if Open and Close directives should be used for "(" and ")" tokens.
|
| + bool AddOpenCloseDirectives;
|
| + // True if clustering directives (for functions) should be inserted.
|
| + bool AddClusterDirectives;
|
| + // The buffer the formatted text is written into.
|
| + std::string Buffer;
|
| + // The base stream of the text formatter, which dumps text into the buffer.
|
| + raw_string_ostream BufStream;
|
| + // The text formatter to use.
|
| + TextFormatter Formatter;
|
| + const std::string CommaText;
|
| + const std::string SpaceText;
|
| + const std::string OpenParenText;
|
| + const std::string CloseParenText;
|
| + const std::string NewlineText;
|
| + const TokenTextDirective Comma;
|
| + SpaceTextDirective Space;
|
| + OpenTextDirective OpenParen;
|
| + CloseTextDirective CloseParen;
|
| + StartClusteringDirective StartCluster;
|
| + FinishClusteringDirective FinishCluster;
|
| + TokenizeTextDirective Tokenize;
|
| + EndlineTextDirective Endline;
|
| + // The parse state of the function parser, used by the tester.
|
| + FormatterState State;
|
| + // The stack of parse states of the function parser. Used to handle
|
| + // nested functions.
|
| + std::vector<FormatterState> FunctionParseStack;
|
| +};
|
| +
|
| +void FormatterTester::WriteToken(const std::string &Token) {
|
| + if (Token == CommaText) {
|
| + Formatter.Tokens() << Comma;
|
| + } else if (Token == SpaceText) {
|
| + Formatter.Tokens() << Space;
|
| + } else if (Token == OpenParenText) {
|
| + if (AddOpenCloseDirectives) {
|
| + Formatter.Tokens() << OpenParen;
|
| + } else {
|
| + Formatter.Tokens() << Token << Tokenize;
|
| + }
|
| + } else if (Token == CloseParenText) {
|
| + if (AddOpenCloseDirectives) {
|
| + Formatter.Tokens() << CloseParen;
|
| + } else {
|
| + Formatter.Tokens() << Token << Tokenize;
|
| + }
|
| + } else if (Token == NewlineText) {
|
| + Formatter.Tokens() << Endline;
|
| + } else {
|
| + Formatter.Tokens() << Token << Tokenize;
|
| + }
|
| +}
|
| +
|
| +std::string FormatterTester::Test(const char *Tokens[],
|
| + size_t NumTokens,
|
| + bool NewAddOpenCloseDirectives,
|
| + bool NewAddClusterDirectives,
|
| + unsigned Indent) {
|
| + AddOpenCloseDirectives = NewAddOpenCloseDirectives;
|
| + AddClusterDirectives = NewAddClusterDirectives;
|
| + for (unsigned i = 0; i < Indent; ++i) Formatter.Inc();
|
| +
|
| + size_t Index = 0;
|
| + unsigned SpaceCount = CollectSpaces(Index, Tokens, NumTokens);
|
| + WriteSpaces(SpaceCount);
|
| + SpaceCount = 0;
|
| +
|
| + // NOTE: We would use ASSERT_LT(Index, NumTokens), but it gets
|
| + // a compile-time error if not inside the TEST macro.
|
| + EXPECT_LT(Index, NumTokens);
|
| + if (Index == NumTokens) return std::string("*W*R*O*N*G*");
|
| +
|
| + // Generate token sequence defined by Tokens.
|
| + std::string CurToken(Tokens[Index++]);
|
| + while (Index < NumTokens) {
|
| + SpaceCount = CollectSpaces(Index, Tokens, NumTokens);
|
| + if (Index == NumTokens) {
|
| + WriteSpaces(SpaceCount);
|
| + SpaceCount = 0;
|
| + break;
|
| + }
|
| + std::string NextToken(Tokens[Index++]);
|
| + InsertClusterDirectives(CurToken, NextToken, true);
|
| + WriteToken(CurToken);
|
| + InsertClusterDirectives(CurToken, NextToken, false);
|
| + WriteSpaces(SpaceCount);
|
| + SpaceCount = 0;
|
| + CurToken = NextToken;
|
| + }
|
| +
|
| + // When reached, all but last token (i.e. CurToken) has been written.
|
| + // Create dummy newline token, so that the last token can be written.
|
| + std::string NextToken(NewlineText);
|
| + InsertClusterDirectives(CurToken, NextToken, true);
|
| + WriteToken(CurToken);
|
| + InsertClusterDirectives(CurToken, NextToken, false);
|
| + WriteSpaces(SpaceCount);
|
| + Formatter.Tokens() << Endline;
|
| +
|
| + EXPECT_TRUE(FunctionParseStack.empty())
|
| + << "Missing close parenthesis in example";
|
| +
|
| + std::string Results = BufStream.str();
|
| + Reset();
|
| + return Results;
|
| +}
|
| +
|
| +void FormatterTester::InsertClusterDirectives(std::string &CurToken,
|
| + std::string &NextToken,
|
| + bool BeforeCurToken) {
|
| + if (!AddClusterDirectives) return;
|
| + switch (State) {
|
| + case LookingForFunction:
|
| + break;
|
| + case StartingFcn:
|
| + if (!BeforeCurToken && CurToken == OpenParenText) {
|
| + // context: <<<f(|>)>>
|
| + // context: <<<f(|><x>)>>
|
| + // context: <<<f(|><x,>><y,> ... <z>)>
|
| + Formatter.Tokens() << FinishCluster;
|
| + State = BeforeFirstArg;
|
| + }
|
| + break;
|
| + case BeforeFirstArg:
|
| + EXPECT_TRUE(BeforeCurToken)
|
| + << "After open paren, but not before current token";
|
| + if (CurToken == CloseParenText) {
|
| + // <<<f(>|)>> => EndFcn2: <<<f(>|)>>
|
| + State = EndFcn2;
|
| + } else {
|
| + // <<<f(>|<x>)>> => InFirstArg: <<<f(><|x>)>>
|
| + // <<<f(>|<x,>>[<y,>]*<z>)> => InFirstArg <<<f(><|x,>>[<y,>]*<z>)>
|
| + State = InFirstArg;
|
| + Formatter.Tokens() << StartCluster;
|
| + }
|
| + break;
|
| + case InFirstArg:
|
| + if (BeforeCurToken && CurToken == CloseParenText) {
|
| + // <<<f(><x|>)>> => EndFcn2: <<<f(><x>|)>>
|
| + Formatter.Tokens() << FinishCluster;
|
| + State = EndFcn2;
|
| + } else if (!BeforeCurToken && CurToken == CommaText) {
|
| + // <<<f(><x,|>>[<y,>]*<z>)> => BetweenArgs: <<<f(><x,>>[|<y,>]*<z>)>
|
| + Formatter.Tokens() << FinishCluster << FinishCluster;
|
| + State = BetweenArgs;
|
| + }
|
| + break;
|
| + case InOtherArg:
|
| + if(BeforeCurToken && CurToken == CloseParenText) {
|
| + // <<<f(><x,>>[<y,>]*<z|>)> => EndFcn1: <<<f(><x,>>[<y,>]*<z>|)>
|
| + Formatter.Tokens() << FinishCluster;
|
| + State = EndFcn1;
|
| + } else if (!BeforeCurToken && CurToken == CommaText) {
|
| + // <<<f(><x,>>[<y,|>]*<z>)> => BetweenArgs: <<<f(><x,>>[<y,>|]*<z>)>
|
| + // => BetweenArgs: <<<f(><x,>>[<y,>]*|<z>)>
|
| + Formatter.Tokens() << FinishCluster;
|
| + State = BetweenArgs;
|
| + }
|
| + break;
|
| + case BetweenArgs:
|
| + // <<<f(><x,>>[|<y,>]*<z>)> => InOtherArg: <<<f(><x,>>[<|y,>]*<z>)>
|
| + // <<<f(><x,>>[<y,>]*|<z>)> => InOtherArg: <<<f(><x,>>[<y,>]*<|z>)>
|
| + EXPECT_TRUE(BeforeCurToken)
|
| + << "Expecting to be before next token after comma";
|
| + Formatter.Tokens() << StartCluster;
|
| + State = InOtherArg;
|
| + break;
|
| + case EndFcn2:
|
| + // <<<f(>)|>> => EndFcn1: <<<f(>)>|>
|
| + // <<<f(><x>)|>> => EndFcn1: <<<f(><x>)>|>
|
| + EXPECT_TRUE(!BeforeCurToken && CurToken == CloseParenText)
|
| + << "Expecting to be after close paren";
|
| + Formatter.Tokens() << FinishCluster;
|
| + // Intentionally drop to the next case.
|
| + case EndFcn1:
|
| + // <<<f(>)>|> => XXX: <<<f(>)>>|
|
| + // <<<f(><x>)>|> => XXX: <<<f(><x>)>>|
|
| + // <<<f(><x,>>[<y,>]*<z>)|> => XXX: <<<f(><x,>>[<y,>]*<z>)>|
|
| + EXPECT_TRUE(!BeforeCurToken && CurToken == CloseParenText)
|
| + << "Expecting to be after close paren";
|
| + Formatter.Tokens() << FinishCluster;
|
| + if (FunctionParseStack.empty()) {
|
| + EXPECT_TRUE(false)
|
| + << "No open paren for corresponding close paren";
|
| + State = LookingForFunction;
|
| + } else {
|
| + State = FunctionParseStack.back();
|
| + FunctionParseStack.pop_back();
|
| + }
|
| + break;
|
| + }
|
| +
|
| + // Check if we are at the beginning of a new function.
|
| + if (BeforeCurToken && NextToken == OpenParenText) {
|
| + // context: <<<|f(>)>>
|
| + // context: <<<|f(><x>)>>
|
| + // context: <<<|f(><x,>><y,> ... <z>)>
|
| + Formatter.Tokens() << StartCluster << StartCluster << StartCluster;
|
| + FunctionParseStack.push_back(State);
|
| + State = StartingFcn;
|
| + }
|
| +}
|
| +
|
| +std::string RunTest(const char *Tokens[],
|
| + size_t NumTokens,
|
| + unsigned LineWidth,
|
| + bool AddOpenCloseDirectives,
|
| + bool AddClusterDirectives,
|
| + unsigned Indent = 0) {
|
| + FormatterTester Tester(LineWidth);
|
| + return Tester.Test(Tokens, NumTokens,
|
| + AddOpenCloseDirectives,
|
| + AddClusterDirectives,
|
| + Indent);
|
| +}
|
| +
|
| +// Test simple single function call.
|
| +TEST(NaClTextFormatterTest, SimpleCall) {
|
| + static const char *Tokens[] = {
|
| + "foobar", "(", "Value1", ",", " ", "Value2", "," , " ", "Value3", ")"
|
| + };
|
| +
|
| + // Print out simple call that can fit on one line.
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 30, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 30, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 30, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 30, false, false));
|
| +
|
| + // Test case where it is one character too long (i.e ")" causes wrapping).
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, Value3\n"
|
| + " )\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 29, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, Value3\n"
|
| + " )\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 29, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, Value3\n"
|
| + " )\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 29, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, Value3\n"
|
| + " )\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 29, false, false));
|
| +
|
| + // Test case where line length matches the beginning of "Value3".
|
| + // Note: Only 3 indents for parenthesis directive, because we
|
| + // stop indenting when there is only 20 columns left in the line
|
| + // (i.e. 23 - 20 == 3).
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, \n"
|
| + " Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 23, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, \n"
|
| + " Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 23, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, \n"
|
| + " Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 23, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2, \n"
|
| + " Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 23, false, false));
|
| +
|
| + // Test case where line length matches the beginning of " Value3"
|
| + // (i.e. the last test, but move the space to the next line).
|
| + // Note: Only 2 indents for parenthesis directive, because we
|
| + // stop indenting when there is only 20 columns left in the line
|
| + // (i.e. 22 - 20 == 2).
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2,\n"
|
| + " Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 22, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2,\n"
|
| + " Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 22, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2,\n"
|
| + " Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 22, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2,\n"
|
| + " Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 22, false, false));
|
| +
|
| + // Test case where last comma causes line wrap.
|
| + EXPECT_EQ(
|
| + "foobar(Value1, \n"
|
| + " Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 21, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2\n"
|
| + " , Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 21, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, \n"
|
| + " Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 21, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, Value2\n"
|
| + " , Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 21, false, false));
|
| +
|
| + // Test case where Value2 runs over the line width.
|
| + EXPECT_EQ(
|
| + "foobar(Value1, \n"
|
| + "Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, \n"
|
| + "Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, \n"
|
| + "Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1, \n"
|
| + "Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, false, false));
|
| +
|
| + // Run test where first comma (after value 1) causes line wrap.
|
| + EXPECT_EQ(
|
| + "foobar(\n"
|
| + "Value1, \n"
|
| + "Value2, \n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 13, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1\n"
|
| + ", Value2, \n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 13, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(\n"
|
| + "Value1, \n"
|
| + "Value2, \n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 13, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(Value1\n"
|
| + ", Value2, \n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 13, false, false));
|
| +
|
| + // Run test where only "foobar(" can fit on a line.
|
| + EXPECT_EQ(
|
| + "foobar(\n"
|
| + "Value1,\n"
|
| + "Value2,\n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 7, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(\n"
|
| + "Value1,\n"
|
| + "Value2,\n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 7, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(\n"
|
| + "Value1,\n"
|
| + "Value2,\n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 7, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar(\n"
|
| + "Value1,\n"
|
| + "Value2,\n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 7, false, false));
|
| +
|
| + // Run case where most tokens don't fit on a line.
|
| + EXPECT_EQ(
|
| + "foobar\n"
|
| + "(\n"
|
| + "Value1\n"
|
| + ", \n"
|
| + "Value2\n"
|
| + ", \n"
|
| + "Value3\n"
|
| + ")\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 4, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar\n"
|
| + "(\n"
|
| + "Value1\n"
|
| + ", \n"
|
| + "Value2\n"
|
| + ", \n"
|
| + "Value3\n"
|
| + ")\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 4, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar\n"
|
| + "(\n"
|
| + "Value1\n"
|
| + ", \n"
|
| + "Value2\n"
|
| + ", \n"
|
| + "Value3\n"
|
| + ")\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 4, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "foobar\n"
|
| + "(\n"
|
| + "Value1\n"
|
| + ", \n"
|
| + "Value2\n"
|
| + ", \n"
|
| + "Value3\n"
|
| + ")\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 4, false, false));
|
| +}
|
| +
|
| +// Test case where call isn't at the beginning of sequence of tokens.
|
| +TEST(NaClTextFormatterTest, TokensPlusSimpleCall) {
|
| + static const char *Tokens[] = {
|
| + "354", " ", "+", " ", "the", " ", "best", " ", "+", " ",
|
| + "foobar", "(", "Value1", ",", " ", "Value2", "," , " ", "Value3", ")"
|
| + };
|
| +
|
| + // Print out where all tokens fit on one line.
|
| + EXPECT_EQ(
|
| + "354 + the best + foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 47, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 47, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 47, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 47, false, false));
|
| +
|
| + // Format cases where buffer is one character too short to fit
|
| + // all tokens.
|
| + EXPECT_EQ(
|
| + "354 + the best + \n"
|
| + " foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 46, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + foobar(Value1, Value2, Value3\n"
|
| + " )\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 46, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + \n"
|
| + " foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 46, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + foobar(Value1, Value2, Value3\n"
|
| + " )\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 46, false, false));
|
| +
|
| + // Show case where function call just fits on continuation line.
|
| + EXPECT_EQ(
|
| + "354 + the best + \n"
|
| + " foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 34, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + foobar(Value1, \n"
|
| + " Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 34, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + \n"
|
| + " foobar(Value1, Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 34, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + foobar(Value1, \n"
|
| + " Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 34, false, false));
|
| +
|
| + // Show case were close parenthesis doesn't fit on continuation line.
|
| + EXPECT_EQ(
|
| + "354 + the best + \n"
|
| + " foobar(Value1, Value2, Value3\n"
|
| + " )\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 33, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + foobar(Value1, \n"
|
| + " Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 33, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + \n"
|
| + " foobar(Value1, Value2, Value3\n"
|
| + " )\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 33, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best + foobar(Value1, \n"
|
| + " Value2, Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 33, false, false));
|
| +
|
| + // Show case where "Value1," just fits on the first continuation line.
|
| + EXPECT_EQ(
|
| + "354 + the best\n"
|
| + "+ \n"
|
| + "foobar(Value1,\n"
|
| + "Value2, Value3\n"
|
| + ")\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 14, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best\n"
|
| + "+ foobar(\n"
|
| + "Value1, Value2\n"
|
| + ", Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 14, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best\n"
|
| + "+ \n"
|
| + "foobar(Value1,\n"
|
| + "Value2, Value3\n"
|
| + ")\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 14, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the best\n"
|
| + "+ foobar(\n"
|
| + "Value1, Value2\n,"
|
| + " Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 14, false, false));
|
| +
|
| + // Show case where "Value1," moves to a new line.
|
| + EXPECT_EQ(
|
| + "354 + the \n"
|
| + "best + \n"
|
| + "foobar(\n"
|
| + "Value1, \n"
|
| + "Value2, \n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 13, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the \n"
|
| + "best + foobar\n"
|
| + "(Value1, \n"
|
| + "Value2, \n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 13, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the \n"
|
| + "best + \n"
|
| + "foobar(\n"
|
| + "Value1, \n"
|
| + "Value2, \n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 13, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + the \n"
|
| + "best + foobar\n"
|
| + "(Value1, \n"
|
| + "Value2, \n"
|
| + "Value3)\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 13, false, false));
|
| +
|
| +}
|
| +
|
| +// Test case of nested functions.
|
| +TEST(NaClTextFormatterTest, NestedCalls) {
|
| + static const char *Tokens[] = {
|
| + "354", " ", "+", " ", "foo", "(", "g", "(", "blah", ")", ",", " ",
|
| + "h", "(", ")", " ", "+", " ", "1", ")", " ", "+", " ", "10"
|
| + };
|
| +
|
| + // Run test case where all text fits on one line.
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, false, false));
|
| +
|
| + // Run test case where all text to end of top-level function call
|
| + // fit on first line.
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1)\n"
|
| + " + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 27, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1)\n"
|
| + " + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 27, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1)\n"
|
| + " + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 27, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1)\n"
|
| + " + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 27, false, false));
|
| +
|
| + // Run test where call to foo doesn't fit on first line.
|
| + EXPECT_EQ(
|
| + "354 + \n"
|
| + " foo(g(blah), h() + 1) \n"
|
| + " + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 26, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1\n"
|
| + " ) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 26, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + \n"
|
| + " foo(g(blah), h() + 1) \n"
|
| + " + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 26, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1\n"
|
| + " ) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 26, false, false));
|
| +
|
| + // Run test where call to foo doesn't fit on continuation line.
|
| + EXPECT_EQ(
|
| + "354 + \n"
|
| + " foo(g(blah), h() + 1\n"
|
| + " ) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 24, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() +\n"
|
| + " 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 24, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + \n"
|
| + " foo(g(blah), h() + 1\n"
|
| + " ) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 24, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() +\n"
|
| + " 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 24, false, false));
|
| +
|
| + // Run test where call to foo doesn't fit on continuation line.
|
| + // Note: same as above, except for loss of continuation indent,
|
| + // since we don't indent when printable space shrinks to 20.
|
| + EXPECT_EQ(
|
| + "354 + \n"
|
| + "foo(g(blah), h() + 1\n"
|
| + ") + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h\n"
|
| + "() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + \n"
|
| + "foo(g(blah), h() + 1\n"
|
| + ") + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h\n"
|
| + "() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, false, false));
|
| +
|
| + // Run case where first argument of foo (i.e. g(blah)) fits
|
| + // on single continuation line.
|
| + EXPECT_EQ(
|
| + "354 + \n"
|
| + "foo(g(blah), \n"
|
| + "h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 19, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), \n"
|
| + "h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 19, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + \n"
|
| + "foo(g(blah), \n"
|
| + "h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 19, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), \n"
|
| + "h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 19, false, false));
|
| +
|
| + // Run case where no room for call to foo and its first argument.
|
| + EXPECT_EQ(
|
| + "354 + \n"
|
| + "foo(\n"
|
| + "g(blah), \n"
|
| + "h() + 1) + \n"
|
| + "10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 11, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g\n"
|
| + "(blah), h()\n"
|
| + "+ 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 11, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + \n"
|
| + "foo(\n"
|
| + "g(blah), \n"
|
| + "h() + 1) + \n"
|
| + "10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 11, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g\n"
|
| + "(blah), h()\n"
|
| + "+ 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 11, false, false));
|
| +}
|
| +
|
| +// Test example with many arguments (which can't be printed on one line).
|
| +TEST(NaClTextFormatterTest, ManyArgs) {
|
| + static const char *Tokens[] = {
|
| + "10", " ", "+", " ", "f", "(",
|
| + "g", "(", "a", ",", " ", "b", ")", ",", " ",
|
| + "abcdef", " ", "+", " ", "gh1196", " ", "+", " ", "z", "(", ")", ",", " ",
|
| + "53267", " ", "*", " ", "1234", " ", "+", " ", "567", ",", " ",
|
| + "why", "(", "is", ",", " ", "this", ",", " ", "so", ",", " ", "hard",
|
| + ",", " ", "to", ",", " ", "do", ")", ",", " ",
|
| + "g", "(", "a", ",", " ", "b", ")", ",", " ",
|
| + "abcdef", " ", "+", " ", "gh1196", " ", "+", " ", "z", "(", ")", ",", " ",
|
| + "53267", " ", "*", " ", "1234", " ", "+", " ", "567", " ", "*", " ",
|
| + "somemorestuff", ")", " ", "+", " ", "1"
|
| + };
|
| +
|
| + // Show layout with linewidth 70
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + " f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, to, do), g(a, b), abcdef + gh1196 + z(),\n"
|
| + " 53267 * 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 70, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, why(is, \n"
|
| + " this, so, hard, to, \n"
|
| + " do), g(a, b), abcdef\n"
|
| + " + gh1196 + z(), 53267 * 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 70, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + " f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, to, do), g(a, b), abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 70, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, why(is, \n"
|
| + " this, so, hard, to, do), g(a, b), abcdef + gh1196 + z(), 53267 * \n"
|
| + " 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 70, false, false));
|
| +
|
| + // Show layout with linewidth 60
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + " f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, to, do), g(a, b), \n"
|
| + " abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 60, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, to, do), g(a, b), abcdef + \n"
|
| + " gh1196 + z(), 53267 * 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 60, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + " f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, to, do), g(a, b), \n"
|
| + " abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 60, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, to, do), g(a, b), abcdef + \n"
|
| + " gh1196 + z(), 53267 * 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 60, false, false));
|
| +
|
| + // Show layout with linewidth 50.
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + " f(g(a, b), abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, to, do), g(a, b), \n"
|
| + " abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 50, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * \n"
|
| + " 1234 + 567, why(is, this, so, hard, to, do)\n"
|
| + " , g(a, b), abcdef + gh1196 + z(), 53267 * \n"
|
| + " 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 50, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + " f(g(a, b), abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, to, do), g(a, b), \n"
|
| + " abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 50, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), abcdef + gh1196 + z(), 53267 * \n"
|
| + " 1234 + 567, why(is, this, so, hard, to, do), g\n"
|
| + " (a, b), abcdef + gh1196 + z(), 53267 * 1234 + \n"
|
| + " 567 * somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 50, false, false));
|
| +
|
| + // Show layout with linewidth 40
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + " f(g(a, b), abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, to, do), \n"
|
| + " g(a, b), abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * somemorestuff\n"
|
| + " ) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 40, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567, why(is, this,\n"
|
| + " so, hard, to, do), g\n"
|
| + " (a, b), abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * \n"
|
| + " somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 40, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + " f(g(a, b), abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, to, do), \n"
|
| + " g(a, b), abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * somemorestuff) \n"
|
| + " + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 40, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567, why(is, this, so\n"
|
| + " , hard, to, do), g(a, b), abcdef + \n"
|
| + " gh1196 + z(), 53267 * 1234 + 567 * \n"
|
| + " somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 40, false, false));
|
| +
|
| + // Show layout with linewidth 30
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + " f(g(a, b), \n"
|
| + " abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, \n"
|
| + " to, do), g(a, b), \n"
|
| + " abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * \n"
|
| + " somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 30, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), abcdef + \n"
|
| + " gh1196 + z(), 53267 * \n"
|
| + " 1234 + 567, why(is, \n"
|
| + " this, so, hard, to, \n"
|
| + " do), g(a, b), abcdef\n"
|
| + " + gh1196 + z(), 53267 *\n"
|
| + " 1234 + 567 * \n"
|
| + " somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 30, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + " f(g(a, b), \n"
|
| + " abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567, \n"
|
| + " why(is, this, so, hard, \n"
|
| + " to, do), g(a, b), \n"
|
| + " abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * \n"
|
| + " somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 30, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), abcdef + \n"
|
| + " gh1196 + z(), 53267 * 1234\n"
|
| + " + 567, why(is, this, so, \n"
|
| + " hard, to, do), g(a, b), \n"
|
| + " abcdef + gh1196 + z(), \n"
|
| + " 53267 * 1234 + 567 * \n"
|
| + " somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 30, false, false));
|
| +
|
| + // Show layout with linewidth 20. Note: Continuation indents no
|
| + // longer apply.
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + "f(g(a, b), \n"
|
| + "abcdef + gh1196 + \n"
|
| + "z(), \n"
|
| + "53267 * 1234 + 567, \n"
|
| + "why(is, this, so, \n"
|
| + "hard, to, do), \n"
|
| + "g(a, b), \n"
|
| + "abcdef + gh1196 + \n"
|
| + "z(), \n"
|
| + "53267 * 1234 + 567 *\n"
|
| + "somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), \n"
|
| + "abcdef + gh1196 + z(\n"
|
| + "), 53267 * 1234 + \n"
|
| + "567, why(is, this, \n"
|
| + "so, hard, to, do), g\n"
|
| + "(a, b), abcdef + \n"
|
| + "gh1196 + z(), 53267 \n"
|
| + "* 1234 + 567 * \n"
|
| + "somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + "f(g(a, b), \n"
|
| + "abcdef + gh1196 + \n"
|
| + "z(), \n"
|
| + "53267 * 1234 + 567, \n"
|
| + "why(is, this, so, \n"
|
| + "hard, to, do), \n"
|
| + "g(a, b), \n"
|
| + "abcdef + gh1196 + \n"
|
| + "z(), \n"
|
| + "53267 * 1234 + 567 *\n"
|
| + "somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a, b), \n"
|
| + "abcdef + gh1196 + z(\n"
|
| + "), 53267 * 1234 + \n"
|
| + "567, why(is, this, \n"
|
| + "so, hard, to, do), g\n"
|
| + "(a, b), abcdef + \n"
|
| + "gh1196 + z(), 53267 \n"
|
| + "* 1234 + 567 * \n"
|
| + "somemorestuff) + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 20, false, false));
|
| +
|
| + // Show layout with linewidth 10, where some tokens ("somemorestuff")
|
| + // exceed the line width requirement.
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + "f(g(a, b),\n"
|
| + "abcdef + \n"
|
| + "gh1196 + \n"
|
| + "z(), \n"
|
| + "53267 * \n"
|
| + "1234 + 567\n"
|
| + ", \n"
|
| + "why(is, \n"
|
| + "this, so, \n"
|
| + "hard, to, \n"
|
| + "do), \n"
|
| + "g(a, b), \n"
|
| + "abcdef + \n"
|
| + "gh1196 + \n"
|
| + "z(), \n"
|
| + "53267 * \n"
|
| + "1234 + 567\n"
|
| + "* \n"
|
| + "somemorestuff\n"
|
| + ") + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 10, true, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a\n"
|
| + ", b), \n"
|
| + "abcdef + \n"
|
| + "gh1196 + z\n"
|
| + "(), 53267 \n"
|
| + "* 1234 + \n"
|
| + "567, why(\n"
|
| + "is, this, \n"
|
| + "so, hard, \n"
|
| + "to, do), g\n"
|
| + "(a, b), \n"
|
| + "abcdef + \n"
|
| + "gh1196 + z\n"
|
| + "(), 53267 \n"
|
| + "* 1234 + \n"
|
| + "567 * \n"
|
| + "somemorestuff\n"
|
| + ") + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 10, true, false));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + \n"
|
| + "f(g(a, b),\n"
|
| + "abcdef + \n"
|
| + "gh1196 + \n"
|
| + "z(), \n"
|
| + "53267 * \n"
|
| + "1234 + 567\n"
|
| + ", \n"
|
| + "why(is, \n"
|
| + "this, so, \n"
|
| + "hard, to, \n"
|
| + "do), \n"
|
| + "g(a, b), \n"
|
| + "abcdef + \n"
|
| + "gh1196 + \n"
|
| + "z(), \n"
|
| + "53267 * \n"
|
| + "1234 + 567\n"
|
| + "* \n"
|
| + "somemorestuff\n"
|
| + ") + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 10, false, true));
|
| +
|
| + EXPECT_EQ(
|
| + "10 + f(g(a\n"
|
| + ", b), \n"
|
| + "abcdef + \n"
|
| + "gh1196 + z\n"
|
| + "(), 53267 \n"
|
| + "* 1234 + \n"
|
| + "567, why(\n"
|
| + "is, this, \n"
|
| + "so, hard, \n"
|
| + "to, do), g\n"
|
| + "(a, b), \n"
|
| + "abcdef + \n"
|
| + "gh1196 + z\n"
|
| + "(), 53267 \n"
|
| + "* 1234 + \n"
|
| + "567 * \n"
|
| + "somemorestuff\n"
|
| + ") + 1\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 10, false, false));
|
| +}
|
| +
|
| +// Turn test case that checks if indenting works.
|
| +TEST(NaClTextFormatterTest, Indenting) {
|
| + static const char *Tokens[] = {
|
| + "354", " ", "+", " ", "foo", "(", "g", "(", "blah", ")", ",", " ",
|
| + "h", "(", ")", " ", "+", " ", "1", ")", " ", "+", " ", "10"
|
| + };
|
| +
|
| + // Run with no indentation.
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, true, true, 0));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, true, false, 0));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, false, true, 0));
|
| +
|
| + EXPECT_EQ(
|
| + "354 + foo(g(blah), h() + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, false, false, 0));
|
| +
|
| + // Run with one indent.
|
| + EXPECT_EQ(
|
| + " 354 + foo(g(blah), h() + 1) + \n"
|
| + " 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, true, true, 1));
|
| +
|
| + EXPECT_EQ(
|
| + " 354 + foo(g(blah), h() + 1) + \n"
|
| + " 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, true, false, 1));
|
| +
|
| + EXPECT_EQ(
|
| + " 354 + foo(g(blah), h() + 1) + \n"
|
| + " 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, false, true, 1));
|
| +
|
| + EXPECT_EQ(
|
| + " 354 + foo(g(blah), h() + 1) + \n"
|
| + " 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, false, false, 1));
|
| +
|
| +
|
| + // Run with two indents.
|
| + EXPECT_EQ(
|
| + " 354 + foo(g(blah), h() + 1) \n"
|
| + " + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, true, true, 2));
|
| +
|
| + EXPECT_EQ(
|
| + " 354 + foo(g(blah), h() + 1) \n"
|
| + " + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, true, false, 2));
|
| +
|
| + EXPECT_EQ(
|
| + " 354 + foo(g(blah), h() + 1) \n"
|
| + " + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, false, true, 2));
|
| +
|
| + EXPECT_EQ(
|
| + " 354 + foo(g(blah), h() + 1) \n"
|
| + " + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, false, false, 2));
|
| +
|
| + // Run with five indents.
|
| + EXPECT_EQ(
|
| + " 354 + \n"
|
| + " foo(g(blah), h() + 1\n"
|
| + " ) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, true, true, 5));
|
| +
|
| + EXPECT_EQ(
|
| + " 354 + foo(g(blah), h()\n"
|
| + " + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, true, false, 5));
|
| +
|
| + EXPECT_EQ(
|
| + " 354 + \n"
|
| + " foo(g(blah), h() + 1\n"
|
| + " ) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, false, true, 5));
|
| +
|
| + EXPECT_EQ(
|
| + " 354 + foo(g(blah), h()\n"
|
| + " + 1) + 10\n",
|
| + RunTest(Tokens, array_lengthof(Tokens), 32, false, false, 5));
|
| +}
|
| +}
|
|
|