Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(488)

Unified Diff: unittests/Bitcode/NaClTextFormatterTest.cpp

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « unittests/Bitcode/NaClParseTypesTest.cpp ('k') | unittests/Support/StreamingMemoryObject.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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));
+}
+}
« no previous file with comments | « unittests/Bitcode/NaClParseTypesTest.cpp ('k') | unittests/Support/StreamingMemoryObject.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698