blob: fddd520eaa4df98348c49d0987be9b02ff3d8294 [file] [log] [blame]
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001//===- unittests/AST/CommentParser.cpp ------ Comment parser tests --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Basic/SourceManager.h"
11#include "clang/Basic/FileManager.h"
12#include "clang/Basic/Diagnostic.h"
13#include "clang/AST/Comment.h"
14#include "clang/AST/CommentLexer.h"
15#include "clang/AST/CommentParser.h"
16#include "clang/AST/CommentSema.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/Support/Allocator.h"
19#include <vector>
20
21#include "gtest/gtest.h"
22
23using namespace llvm;
24using namespace clang;
25
26namespace clang {
27namespace comments {
28
29namespace {
30
31const bool DEBUG = true;
32
33class CommentParserTest : public ::testing::Test {
34protected:
35 CommentParserTest()
36 : FileMgr(FileMgrOpts),
37 DiagID(new DiagnosticIDs()),
38 Diags(DiagID, new IgnoringDiagConsumer()),
39 SourceMgr(Diags, FileMgr) {
40 }
41
42 FileSystemOptions FileMgrOpts;
43 FileManager FileMgr;
44 IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
45 DiagnosticsEngine Diags;
46 SourceManager SourceMgr;
47 llvm::BumpPtrAllocator Allocator;
48
49 FullComment *parseString(const char *Source);
50};
51
52FullComment *CommentParserTest::parseString(const char *Source) {
53 MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source);
54 FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
55 SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
56
Dmitri Gribenko477a9f52012-07-27 20:37:06 +000057 comments::Lexer L(Allocator, Begin, CommentOptions(),
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000058 Source, Source + strlen(Source));
59
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +000060 comments::Sema S(Allocator, SourceMgr, Diags);
61 comments::Parser P(L, S, Allocator, SourceMgr, Diags);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000062 comments::FullComment *FC = P.parseFullComment();
63
64 if (DEBUG) {
65 llvm::errs() << "=== Source:\n" << Source << "\n=== AST:\n";
66 FC->dump(SourceMgr);
67 }
68
69 Token Tok;
70 L.lex(Tok);
71 if (Tok.is(tok::eof))
72 return FC;
73 else
74 return NULL;
75}
76
77::testing::AssertionResult HasChildCount(const Comment *C, size_t Count) {
78 if (!C)
79 return ::testing::AssertionFailure() << "Comment is NULL";
80
81 if (Count != C->child_count())
82 return ::testing::AssertionFailure()
83 << "Count = " << Count
84 << ", child_count = " << C->child_count();
85
86 return ::testing::AssertionSuccess();
87}
88
89template <typename T>
90::testing::AssertionResult GetChildAt(const Comment *C,
91 size_t Idx,
92 T *&Child) {
93 if (!C)
94 return ::testing::AssertionFailure() << "Comment is NULL";
95
96 if (Idx >= C->child_count())
97 return ::testing::AssertionFailure()
98 << "Idx out of range. Idx = " << Idx
99 << ", child_count = " << C->child_count();
100
101 Comment::child_iterator I = C->child_begin() + Idx;
102 Comment *CommentChild = *I;
103 if (!CommentChild)
104 return ::testing::AssertionFailure() << "Child is NULL";
105
106 Child = dyn_cast<T>(CommentChild);
107 if (!Child)
108 return ::testing::AssertionFailure()
109 << "Child is not of requested type, but a "
110 << CommentChild->getCommentKindName();
111
112 return ::testing::AssertionSuccess();
113}
114
115::testing::AssertionResult HasTextAt(const Comment *C,
116 size_t Idx,
117 StringRef Text) {
118 TextComment *TC;
119 ::testing::AssertionResult AR = GetChildAt(C, Idx, TC);
120 if (!AR)
121 return AR;
122
123 StringRef ActualText = TC->getText();
124 if (ActualText != Text)
125 return ::testing::AssertionFailure()
126 << "TextComment has text \"" << ActualText.str() << "\", "
127 "expected \"" << Text.str() << "\"";
128
129 if (TC->hasTrailingNewline())
130 return ::testing::AssertionFailure()
131 << "TextComment has a trailing newline";
132
133 return ::testing::AssertionSuccess();
134}
135
136::testing::AssertionResult HasTextWithNewlineAt(const Comment *C,
137 size_t Idx,
138 StringRef Text) {
139 TextComment *TC;
140 ::testing::AssertionResult AR = GetChildAt(C, Idx, TC);
141 if (!AR)
142 return AR;
143
144 StringRef ActualText = TC->getText();
145 if (ActualText != Text)
146 return ::testing::AssertionFailure()
147 << "TextComment has text \"" << ActualText.str() << "\", "
148 "expected \"" << Text.str() << "\"";
149
150 if (!TC->hasTrailingNewline())
151 return ::testing::AssertionFailure()
152 << "TextComment has no trailing newline";
153
154 return ::testing::AssertionSuccess();
155}
156
157::testing::AssertionResult HasBlockCommandAt(const Comment *C,
158 size_t Idx,
159 BlockCommandComment *&BCC,
160 StringRef Name,
161 ParagraphComment *&Paragraph) {
162 ::testing::AssertionResult AR = GetChildAt(C, Idx, BCC);
163 if (!AR)
164 return AR;
165
166 StringRef ActualName = BCC->getCommandName();
167 if (ActualName != Name)
168 return ::testing::AssertionFailure()
169 << "BlockCommandComment has name \"" << ActualName.str() << "\", "
170 "expected \"" << Name.str() << "\"";
171
172 Paragraph = BCC->getParagraph();
173
174 return ::testing::AssertionSuccess();
175}
176
177::testing::AssertionResult HasParamCommandAt(
178 const Comment *C,
179 size_t Idx,
180 ParamCommandComment *&PCC,
181 StringRef CommandName,
182 ParamCommandComment::PassDirection Direction,
183 bool IsDirectionExplicit,
184 StringRef ParamName,
185 ParagraphComment *&Paragraph) {
186 ::testing::AssertionResult AR = GetChildAt(C, Idx, PCC);
187 if (!AR)
188 return AR;
189
190 StringRef ActualCommandName = PCC->getCommandName();
191 if (ActualCommandName != CommandName)
192 return ::testing::AssertionFailure()
193 << "ParamCommandComment has name \"" << ActualCommandName.str() << "\", "
194 "expected \"" << CommandName.str() << "\"";
195
196 if (PCC->getDirection() != Direction)
197 return ::testing::AssertionFailure()
198 << "ParamCommandComment has direction " << PCC->getDirection() << ", "
199 "expected " << Direction;
200
201 if (PCC->isDirectionExplicit() != IsDirectionExplicit)
202 return ::testing::AssertionFailure()
203 << "ParamCommandComment has "
204 << (PCC->isDirectionExplicit() ? "explicit" : "implicit")
205 << " direction, "
206 "expected " << (IsDirectionExplicit ? "explicit" : "implicit");
207
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000208 if (!PCC->hasParamName())
209 return ::testing::AssertionFailure()
210 << "ParamCommandComment has no parameter name";
211
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000212 StringRef ActualParamName = PCC->getParamName();
213 if (ActualParamName != ParamName)
214 return ::testing::AssertionFailure()
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000215 << "ParamCommandComment has parameter name \"" << ActualParamName.str()
216 << "\", "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000217 "expected \"" << ParamName.str() << "\"";
218
219 Paragraph = PCC->getParagraph();
220
221 return ::testing::AssertionSuccess();
222}
223
Dmitri Gribenko96b09862012-07-31 22:37:06 +0000224::testing::AssertionResult HasTParamCommandAt(
225 const Comment *C,
226 size_t Idx,
227 TParamCommandComment *&TPCC,
228 StringRef CommandName,
229 StringRef ParamName,
230 ParagraphComment *&Paragraph) {
231 ::testing::AssertionResult AR = GetChildAt(C, Idx, TPCC);
232 if (!AR)
233 return AR;
234
235 StringRef ActualCommandName = TPCC->getCommandName();
236 if (ActualCommandName != CommandName)
237 return ::testing::AssertionFailure()
238 << "TParamCommandComment has name \"" << ActualCommandName.str() << "\", "
239 "expected \"" << CommandName.str() << "\"";
240
241 if (!TPCC->hasParamName())
242 return ::testing::AssertionFailure()
243 << "TParamCommandComment has no parameter name";
244
245 StringRef ActualParamName = TPCC->getParamName();
246 if (ActualParamName != ParamName)
247 return ::testing::AssertionFailure()
248 << "TParamCommandComment has parameter name \"" << ActualParamName.str()
249 << "\", "
250 "expected \"" << ParamName.str() << "\"";
251
252 Paragraph = TPCC->getParagraph();
253
254 return ::testing::AssertionSuccess();
255}
256
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000257::testing::AssertionResult HasInlineCommandAt(const Comment *C,
258 size_t Idx,
259 InlineCommandComment *&ICC,
260 StringRef Name) {
261 ::testing::AssertionResult AR = GetChildAt(C, Idx, ICC);
262 if (!AR)
263 return AR;
264
265 StringRef ActualName = ICC->getCommandName();
266 if (ActualName != Name)
267 return ::testing::AssertionFailure()
268 << "InlineCommandComment has name \"" << ActualName.str() << "\", "
269 "expected \"" << Name.str() << "\"";
270
271 return ::testing::AssertionSuccess();
272}
273
274struct NoArgs {};
275
276::testing::AssertionResult HasInlineCommandAt(const Comment *C,
277 size_t Idx,
278 InlineCommandComment *&ICC,
279 StringRef Name,
280 NoArgs) {
281 ::testing::AssertionResult AR = HasInlineCommandAt(C, Idx, ICC, Name);
282 if (!AR)
283 return AR;
284
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000285 if (ICC->getNumArgs() != 0)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000286 return ::testing::AssertionFailure()
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000287 << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000288 "expected 0";
289
290 return ::testing::AssertionSuccess();
291}
292
293::testing::AssertionResult HasInlineCommandAt(const Comment *C,
294 size_t Idx,
295 InlineCommandComment *&ICC,
296 StringRef Name,
297 StringRef Arg) {
298 ::testing::AssertionResult AR = HasInlineCommandAt(C, Idx, ICC, Name);
299 if (!AR)
300 return AR;
301
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000302 if (ICC->getNumArgs() != 1)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000303 return ::testing::AssertionFailure()
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000304 << "InlineCommandComment has " << ICC->getNumArgs() << " arg(s), "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000305 "expected 1";
306
307 StringRef ActualArg = ICC->getArgText(0);
308 if (ActualArg != Arg)
309 return ::testing::AssertionFailure()
310 << "InlineCommandComment has argument \"" << ActualArg.str() << "\", "
311 "expected \"" << Arg.str() << "\"";
312
313 return ::testing::AssertionSuccess();
314}
315
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000316::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
317 size_t Idx,
318 HTMLStartTagComment *&HST,
319 StringRef TagName) {
320 ::testing::AssertionResult AR = GetChildAt(C, Idx, HST);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000321 if (!AR)
322 return AR;
323
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000324 StringRef ActualTagName = HST->getTagName();
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000325 if (ActualTagName != TagName)
326 return ::testing::AssertionFailure()
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000327 << "HTMLStartTagComment has name \"" << ActualTagName.str() << "\", "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000328 "expected \"" << TagName.str() << "\"";
329
330 return ::testing::AssertionSuccess();
331}
332
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000333struct SelfClosing {};
334
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000335::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
336 size_t Idx,
337 HTMLStartTagComment *&HST,
338 StringRef TagName,
339 SelfClosing) {
340 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000341 if (!AR)
342 return AR;
343
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000344 if (!HST->isSelfClosing())
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000345 return ::testing::AssertionFailure()
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000346 << "HTMLStartTagComment is not self-closing";
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000347
348 return ::testing::AssertionSuccess();
349}
350
351
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000352struct NoAttrs {};
353
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000354::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
355 size_t Idx,
356 HTMLStartTagComment *&HST,
357 StringRef TagName,
358 NoAttrs) {
359 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000360 if (!AR)
361 return AR;
362
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000363 if (HST->isSelfClosing())
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000364 return ::testing::AssertionFailure()
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000365 << "HTMLStartTagComment is self-closing";
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000366
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000367 if (HST->getNumAttrs() != 0)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000368 return ::testing::AssertionFailure()
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000369 << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000370 "expected 0";
371
372 return ::testing::AssertionSuccess();
373}
374
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000375::testing::AssertionResult HasHTMLStartTagAt(const Comment *C,
376 size_t Idx,
377 HTMLStartTagComment *&HST,
378 StringRef TagName,
379 StringRef AttrName,
380 StringRef AttrValue) {
381 ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000382 if (!AR)
383 return AR;
384
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000385 if (HST->isSelfClosing())
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000386 return ::testing::AssertionFailure()
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000387 << "HTMLStartTagComment is self-closing";
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000388
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000389 if (HST->getNumAttrs() != 1)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000390 return ::testing::AssertionFailure()
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000391 << "HTMLStartTagComment has " << HST->getNumAttrs() << " attr(s), "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000392 "expected 1";
393
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000394 StringRef ActualName = HST->getAttr(0).Name;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000395 if (ActualName != AttrName)
396 return ::testing::AssertionFailure()
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000397 << "HTMLStartTagComment has attr \"" << ActualName.str() << "\", "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000398 "expected \"" << AttrName.str() << "\"";
399
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000400 StringRef ActualValue = HST->getAttr(0).Value;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000401 if (ActualValue != AttrValue)
402 return ::testing::AssertionFailure()
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000403 << "HTMLStartTagComment has attr value \"" << ActualValue.str() << "\", "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000404 "expected \"" << AttrValue.str() << "\"";
405
406 return ::testing::AssertionSuccess();
407}
408
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000409::testing::AssertionResult HasHTMLEndTagAt(const Comment *C,
410 size_t Idx,
411 HTMLEndTagComment *&HET,
412 StringRef TagName) {
413 ::testing::AssertionResult AR = GetChildAt(C, Idx, HET);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000414 if (!AR)
415 return AR;
416
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000417 StringRef ActualTagName = HET->getTagName();
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000418 if (ActualTagName != TagName)
419 return ::testing::AssertionFailure()
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000420 << "HTMLEndTagComment has name \"" << ActualTagName.str() << "\", "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000421 "expected \"" << TagName.str() << "\"";
422
423 return ::testing::AssertionSuccess();
424}
425
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +0000426::testing::AssertionResult HasParagraphCommentAt(const Comment *C,
427 size_t Idx,
428 StringRef Text) {
429 ParagraphComment *PC;
430
431 {
432 ::testing::AssertionResult AR = GetChildAt(C, Idx, PC);
433 if (!AR)
434 return AR;
435 }
436
437 {
438 ::testing::AssertionResult AR = HasChildCount(PC, 1);
439 if (!AR)
440 return AR;
441 }
442
443 {
444 ::testing::AssertionResult AR = HasTextAt(PC, 0, Text);
445 if (!AR)
446 return AR;
447 }
448
449 return ::testing::AssertionSuccess();
450}
451
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000452::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
453 size_t Idx,
454 VerbatimBlockComment *&VBC,
Dmitri Gribenko9f08f492012-07-20 20:18:53 +0000455 StringRef Name,
456 StringRef CloseName) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000457 ::testing::AssertionResult AR = GetChildAt(C, Idx, VBC);
458 if (!AR)
459 return AR;
460
461 StringRef ActualName = VBC->getCommandName();
462 if (ActualName != Name)
463 return ::testing::AssertionFailure()
464 << "VerbatimBlockComment has name \"" << ActualName.str() << "\", "
465 "expected \"" << Name.str() << "\"";
466
Dmitri Gribenko9f08f492012-07-20 20:18:53 +0000467 StringRef ActualCloseName = VBC->getCloseName();
468 if (ActualCloseName != CloseName)
469 return ::testing::AssertionFailure()
470 << "VerbatimBlockComment has closing command name \""
471 << ActualCloseName.str() << "\", "
472 "expected \"" << CloseName.str() << "\"";
473
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000474 return ::testing::AssertionSuccess();
475}
476
477struct NoLines {};
Dmitri Gribenko9f08f492012-07-20 20:18:53 +0000478struct Lines {};
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000479
480::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
481 size_t Idx,
482 VerbatimBlockComment *&VBC,
483 StringRef Name,
Dmitri Gribenko9f08f492012-07-20 20:18:53 +0000484 StringRef CloseName,
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000485 NoLines) {
Dmitri Gribenko9f08f492012-07-20 20:18:53 +0000486 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name,
487 CloseName);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000488 if (!AR)
489 return AR;
490
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000491 if (VBC->getNumLines() != 0)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000492 return ::testing::AssertionFailure()
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000493 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000494 "expected 0";
495
496 return ::testing::AssertionSuccess();
497}
498
499::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
500 size_t Idx,
501 VerbatimBlockComment *&VBC,
502 StringRef Name,
Dmitri Gribenko9f08f492012-07-20 20:18:53 +0000503 StringRef CloseName,
504 Lines,
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000505 StringRef Line0) {
Dmitri Gribenko9f08f492012-07-20 20:18:53 +0000506 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name,
507 CloseName);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000508 if (!AR)
509 return AR;
510
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000511 if (VBC->getNumLines() != 1)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000512 return ::testing::AssertionFailure()
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000513 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000514 "expected 1";
515
516 StringRef ActualLine0 = VBC->getText(0);
517 if (ActualLine0 != Line0)
518 return ::testing::AssertionFailure()
519 << "VerbatimBlockComment has lines[0] \"" << ActualLine0.str() << "\", "
520 "expected \"" << Line0.str() << "\"";
521
522 return ::testing::AssertionSuccess();
523}
524
525::testing::AssertionResult HasVerbatimBlockAt(const Comment *C,
526 size_t Idx,
527 VerbatimBlockComment *&VBC,
528 StringRef Name,
Dmitri Gribenko9f08f492012-07-20 20:18:53 +0000529 StringRef CloseName,
530 Lines,
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000531 StringRef Line0,
532 StringRef Line1) {
Dmitri Gribenko9f08f492012-07-20 20:18:53 +0000533 ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name,
534 CloseName);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000535 if (!AR)
536 return AR;
537
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000538 if (VBC->getNumLines() != 2)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000539 return ::testing::AssertionFailure()
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000540 << "VerbatimBlockComment has " << VBC->getNumLines() << " lines(s), "
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000541 "expected 2";
542
543 StringRef ActualLine0 = VBC->getText(0);
544 if (ActualLine0 != Line0)
545 return ::testing::AssertionFailure()
546 << "VerbatimBlockComment has lines[0] \"" << ActualLine0.str() << "\", "
547 "expected \"" << Line0.str() << "\"";
548
549 StringRef ActualLine1 = VBC->getText(1);
550 if (ActualLine1 != Line1)
551 return ::testing::AssertionFailure()
552 << "VerbatimBlockComment has lines[1] \"" << ActualLine1.str() << "\", "
553 "expected \"" << Line1.str() << "\"";
554
555 return ::testing::AssertionSuccess();
556}
557
558::testing::AssertionResult HasVerbatimLineAt(const Comment *C,
559 size_t Idx,
560 VerbatimLineComment *&VLC,
561 StringRef Name,
562 StringRef Text) {
563 ::testing::AssertionResult AR = GetChildAt(C, Idx, VLC);
564 if (!AR)
565 return AR;
566
567 StringRef ActualName = VLC->getCommandName();
568 if (ActualName != Name)
569 return ::testing::AssertionFailure()
570 << "VerbatimLineComment has name \"" << ActualName.str() << "\", "
571 "expected \"" << Name.str() << "\"";
572
573 StringRef ActualText = VLC->getText();
574 if (ActualText != Text)
575 return ::testing::AssertionFailure()
576 << "VerbatimLineComment has text \"" << ActualText.str() << "\", "
577 "expected \"" << Text.str() << "\"";
578
579 return ::testing::AssertionSuccess();
580}
581
582
583TEST_F(CommentParserTest, Basic1) {
584 const char *Source = "//";
585
586 FullComment *FC = parseString(Source);
587 ASSERT_TRUE(HasChildCount(FC, 0));
588}
589
590TEST_F(CommentParserTest, Basic2) {
591 const char *Source = "// Meow";
592
593 FullComment *FC = parseString(Source);
594 ASSERT_TRUE(HasChildCount(FC, 1));
595
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +0000596 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Meow"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000597}
598
599TEST_F(CommentParserTest, Basic3) {
600 const char *Source =
601 "// Aaa\n"
602 "// Bbb";
603
604 FullComment *FC = parseString(Source);
605 ASSERT_TRUE(HasChildCount(FC, 1));
606
607 {
608 ParagraphComment *PC;
609 ASSERT_TRUE(GetChildAt(FC, 0, PC));
610
611 ASSERT_TRUE(HasChildCount(PC, 2));
612 ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa"));
613 ASSERT_TRUE(HasTextAt(PC, 1, " Bbb"));
614 }
615}
616
617TEST_F(CommentParserTest, Paragraph1) {
618 const char *Sources[] = {
619 "// Aaa\n"
620 "//\n"
621 "// Bbb",
622
623 "// Aaa\n"
624 "//\n"
625 "//\n"
626 "// Bbb",
627 };
628
629
630 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
631 FullComment *FC = parseString(Sources[i]);
632 ASSERT_TRUE(HasChildCount(FC, 2));
633
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +0000634 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Aaa"));
635 ASSERT_TRUE(HasParagraphCommentAt(FC, 1, " Bbb"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000636 }
637}
638
639TEST_F(CommentParserTest, Paragraph2) {
640 const char *Source =
641 "// \\brief Aaa\n"
642 "//\n"
643 "// Bbb";
644
645 FullComment *FC = parseString(Source);
646 ASSERT_TRUE(HasChildCount(FC, 3));
647
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +0000648 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000649 {
650 BlockCommandComment *BCC;
651 ParagraphComment *PC;
652 ASSERT_TRUE(HasBlockCommandAt(FC, 1, BCC, "brief", PC));
653
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +0000654 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Aaa"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000655 }
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +0000656 ASSERT_TRUE(HasParagraphCommentAt(FC, 2, " Bbb"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000657}
658
659TEST_F(CommentParserTest, Paragraph3) {
660 const char *Source = "// \\brief \\author";
661
662 FullComment *FC = parseString(Source);
663 ASSERT_TRUE(HasChildCount(FC, 3));
664
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +0000665 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000666 {
667 BlockCommandComment *BCC;
668 ParagraphComment *PC;
669 ASSERT_TRUE(HasBlockCommandAt(FC, 1, BCC, "brief", PC));
670
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +0000671 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000672 }
673 {
674 BlockCommandComment *BCC;
675 ParagraphComment *PC;
676 ASSERT_TRUE(HasBlockCommandAt(FC, 2, BCC, "author", PC));
677
678 ASSERT_TRUE(GetChildAt(BCC, 0, PC));
679 ASSERT_TRUE(HasChildCount(PC, 0));
680 }
681}
682
683TEST_F(CommentParserTest, Paragraph4) {
684 const char *Source =
685 "// \\brief Aaa\n"
686 "// Bbb \\author\n"
687 "// Ccc";
688
689 FullComment *FC = parseString(Source);
690 ASSERT_TRUE(HasChildCount(FC, 3));
691
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +0000692 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000693 {
694 BlockCommandComment *BCC;
695 ParagraphComment *PC;
696 ASSERT_TRUE(HasBlockCommandAt(FC, 1, BCC, "brief", PC));
697
698 ASSERT_TRUE(GetChildAt(BCC, 0, PC));
699 ASSERT_TRUE(HasChildCount(PC, 2));
700 ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa"));
701 ASSERT_TRUE(HasTextAt(PC, 1, " Bbb "));
702 }
703 {
704 BlockCommandComment *BCC;
705 ParagraphComment *PC;
706 ASSERT_TRUE(HasBlockCommandAt(FC, 2, BCC, "author", PC));
707
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +0000708 ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Ccc"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000709 }
710}
711
712TEST_F(CommentParserTest, ParamCommand1) {
Dmitri Gribenko3ccc1732012-07-30 16:52:51 +0000713 const char *Source = "// \\param aaa";
714
715 FullComment *FC = parseString(Source);
716 ASSERT_TRUE(HasChildCount(FC, 2));
717
718 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
719 {
720 ParamCommandComment *PCC;
721 ParagraphComment *PC;
722 ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
723 ParamCommandComment::In,
724 /* IsDirectionExplicit = */ false,
725 "aaa", PC));
726 ASSERT_TRUE(HasChildCount(PCC, 1));
727 ASSERT_TRUE(HasChildCount(PC, 0));
728 }
729}
730
731TEST_F(CommentParserTest, ParamCommand2) {
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000732 const char *Sources[] = {
733 "// \\param aaa Bbb\n",
734 "// \\param\n"
735 "// aaa Bbb\n",
736 "// \\param \n"
737 "// aaa Bbb\n",
738 "// \\param aaa\n"
739 "// Bbb\n"
740 };
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000741
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000742 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
743 FullComment *FC = parseString(Sources[i]);
744 ASSERT_TRUE(HasChildCount(FC, 2));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000745
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000746 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
747 {
748 ParamCommandComment *PCC;
749 ParagraphComment *PC;
750 ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
751 ParamCommandComment::In,
752 /* IsDirectionExplicit = */ false,
753 "aaa", PC));
754 ASSERT_TRUE(HasChildCount(PCC, 1));
755 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
756 }
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000757 }
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000758}
759
Dmitri Gribenko3ccc1732012-07-30 16:52:51 +0000760TEST_F(CommentParserTest, ParamCommand3) {
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000761 const char *Sources[] = {
762 "// \\param [in] aaa Bbb\n",
Dmitri Gribenkod076e012012-08-01 23:49:32 +0000763 "// \\param[in] aaa Bbb\n",
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000764 "// \\param\n"
765 "// [in] aaa Bbb\n",
766 "// \\param [in]\n"
767 "// aaa Bbb\n",
768 "// \\param [in] aaa\n"
769 "// Bbb\n",
770 };
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000771
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000772 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
773 FullComment *FC = parseString(Sources[i]);
774 ASSERT_TRUE(HasChildCount(FC, 2));
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000775
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000776 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
777 {
778 ParamCommandComment *PCC;
779 ParagraphComment *PC;
780 ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
781 ParamCommandComment::In,
782 /* IsDirectionExplicit = */ true,
783 "aaa", PC));
784 ASSERT_TRUE(HasChildCount(PCC, 1));
785 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
786 }
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000787 }
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000788}
789
Dmitri Gribenko3ccc1732012-07-30 16:52:51 +0000790TEST_F(CommentParserTest, ParamCommand4) {
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000791 const char *Sources[] = {
792 "// \\param [out] aaa Bbb\n",
Dmitri Gribenkod076e012012-08-01 23:49:32 +0000793 "// \\param[out] aaa Bbb\n",
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000794 "// \\param\n"
795 "// [out] aaa Bbb\n",
796 "// \\param [out]\n"
797 "// aaa Bbb\n",
798 "// \\param [out] aaa\n"
799 "// Bbb\n",
800 };
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000801
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000802 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
803 FullComment *FC = parseString(Sources[i]);
804 ASSERT_TRUE(HasChildCount(FC, 2));
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000805
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000806 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
807 {
808 ParamCommandComment *PCC;
809 ParagraphComment *PC;
810 ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
811 ParamCommandComment::Out,
812 /* IsDirectionExplicit = */ true,
813 "aaa", PC));
814 ASSERT_TRUE(HasChildCount(PCC, 1));
815 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
816 }
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000817 }
818}
819
Dmitri Gribenko3ccc1732012-07-30 16:52:51 +0000820TEST_F(CommentParserTest, ParamCommand5) {
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000821 const char *Sources[] = {
822 "// \\param [in,out] aaa Bbb\n",
Dmitri Gribenkod076e012012-08-01 23:49:32 +0000823 "// \\param[in,out] aaa Bbb\n",
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000824 "// \\param [in, out] aaa Bbb\n",
825 "// \\param [in,\n"
826 "// out] aaa Bbb\n",
827 "// \\param [in,out]\n"
828 "// aaa Bbb\n",
829 "// \\param [in,out] aaa\n"
830 "// Bbb\n"
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000831 };
832
833 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
834 FullComment *FC = parseString(Sources[i]);
835 ASSERT_TRUE(HasChildCount(FC, 2));
836
837 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
838 {
839 ParamCommandComment *PCC;
840 ParagraphComment *PC;
841 ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
842 ParamCommandComment::InOut,
843 /* IsDirectionExplicit = */ true,
844 "aaa", PC));
845 ASSERT_TRUE(HasChildCount(PCC, 1));
846 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
847 }
848 }
849}
850
Dmitri Gribenko3ccc1732012-07-30 16:52:51 +0000851TEST_F(CommentParserTest, ParamCommand6) {
Dmitri Gribenkofd939162012-07-24 16:10:47 +0000852 const char *Source =
853 "// \\param aaa \\% Bbb \\$ ccc\n";
854
855 FullComment *FC = parseString(Source);
856 ASSERT_TRUE(HasChildCount(FC, 2));
857
858 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
859 {
860 ParamCommandComment *PCC;
861 ParagraphComment *PC;
862 ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
863 ParamCommandComment::In,
864 /* IsDirectionExplicit = */ false,
865 "aaa", PC));
866 ASSERT_TRUE(HasChildCount(PCC, 1));
867
868 ASSERT_TRUE(HasChildCount(PC, 5));
869 ASSERT_TRUE(HasTextAt(PC, 0, " "));
870 ASSERT_TRUE(HasTextAt(PC, 1, "%"));
871 ASSERT_TRUE(HasTextAt(PC, 2, " Bbb "));
872 ASSERT_TRUE(HasTextAt(PC, 3, "$"));
873 ASSERT_TRUE(HasTextAt(PC, 4, " ccc"));
874 }
875}
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000876
Dmitri Gribenko96b09862012-07-31 22:37:06 +0000877TEST_F(CommentParserTest, TParamCommand1) {
878 const char *Sources[] = {
879 "// \\tparam aaa Bbb\n",
880 "// \\tparam\n"
881 "// aaa Bbb\n",
882 "// \\tparam \n"
883 "// aaa Bbb\n",
884 "// \\tparam aaa\n"
885 "// Bbb\n"
886 };
887
888 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
889 FullComment *FC = parseString(Sources[i]);
890 ASSERT_TRUE(HasChildCount(FC, 2));
891
892 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
893 {
894 TParamCommandComment *TPCC;
895 ParagraphComment *PC;
896 ASSERT_TRUE(HasTParamCommandAt(FC, 1, TPCC, "tparam",
897 "aaa", PC));
898 ASSERT_TRUE(HasChildCount(TPCC, 1));
899 ASSERT_TRUE(HasParagraphCommentAt(TPCC, 0, " Bbb"));
900 }
901 }
902}
903
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000904TEST_F(CommentParserTest, InlineCommand1) {
905 const char *Source = "// \\c";
906
907 FullComment *FC = parseString(Source);
908 ASSERT_TRUE(HasChildCount(FC, 1));
909
910 {
911 ParagraphComment *PC;
912 InlineCommandComment *ICC;
913 ASSERT_TRUE(GetChildAt(FC, 0, PC));
914
915 ASSERT_TRUE(HasChildCount(PC, 2));
916 ASSERT_TRUE(HasTextAt(PC, 0, " "));
917 ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", NoArgs()));
918 }
919}
920
921TEST_F(CommentParserTest, InlineCommand2) {
922 const char *Source = "// \\c ";
923
924 FullComment *FC = parseString(Source);
925 ASSERT_TRUE(HasChildCount(FC, 1));
926
927 {
928 ParagraphComment *PC;
929 InlineCommandComment *ICC;
930 ASSERT_TRUE(GetChildAt(FC, 0, PC));
931
932 ASSERT_TRUE(HasChildCount(PC, 3));
933 ASSERT_TRUE(HasTextAt(PC, 0, " "));
934 ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", NoArgs()));
935 ASSERT_TRUE(HasTextAt(PC, 2, " "));
936 }
937}
938
939TEST_F(CommentParserTest, InlineCommand3) {
940 const char *Source = "// \\c aaa\n";
941
942 FullComment *FC = parseString(Source);
943 ASSERT_TRUE(HasChildCount(FC, 1));
944
945 {
946 ParagraphComment *PC;
947 InlineCommandComment *ICC;
948 ASSERT_TRUE(GetChildAt(FC, 0, PC));
949
950 ASSERT_TRUE(HasChildCount(PC, 2));
951 ASSERT_TRUE(HasTextAt(PC, 0, " "));
952 ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", "aaa"));
953 }
954}
955
956TEST_F(CommentParserTest, InlineCommand4) {
957 const char *Source = "// \\c aaa bbb";
958
959 FullComment *FC = parseString(Source);
960 ASSERT_TRUE(HasChildCount(FC, 1));
961
962 {
963 ParagraphComment *PC;
964 InlineCommandComment *ICC;
965 ASSERT_TRUE(GetChildAt(FC, 0, PC));
966
967 ASSERT_TRUE(HasChildCount(PC, 3));
968 ASSERT_TRUE(HasTextAt(PC, 0, " "));
969 ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", "aaa"));
970 ASSERT_TRUE(HasTextAt(PC, 2, " bbb"));
971 }
972}
973
974TEST_F(CommentParserTest, InlineCommand5) {
975 const char *Source = "// \\unknown aaa\n";
976
977 FullComment *FC = parseString(Source);
978 ASSERT_TRUE(HasChildCount(FC, 1));
979
980 {
981 ParagraphComment *PC;
982 InlineCommandComment *ICC;
983 ASSERT_TRUE(GetChildAt(FC, 0, PC));
984
985 ASSERT_TRUE(HasChildCount(PC, 3));
986 ASSERT_TRUE(HasTextAt(PC, 0, " "));
987 ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "unknown", NoArgs()));
988 ASSERT_TRUE(HasTextAt(PC, 2, " aaa"));
989 }
990}
991
992TEST_F(CommentParserTest, HTML1) {
993 const char *Sources[] = {
994 "// <a",
995 "// <a>",
996 "// <a >"
997 };
998
999 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1000 FullComment *FC = parseString(Sources[i]);
1001 ASSERT_TRUE(HasChildCount(FC, 1));
1002
1003 {
1004 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001005 HTMLStartTagComment *HST;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001006 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1007
1008 ASSERT_TRUE(HasChildCount(PC, 2));
1009 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001010 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", NoAttrs()));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001011 }
1012 }
1013}
1014
1015TEST_F(CommentParserTest, HTML2) {
1016 const char *Sources[] = {
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001017 "// <br/>",
1018 "// <br />"
1019 };
1020
1021 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1022 FullComment *FC = parseString(Sources[i]);
1023 ASSERT_TRUE(HasChildCount(FC, 1));
1024
1025 {
1026 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001027 HTMLStartTagComment *HST;
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001028 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1029
1030 ASSERT_TRUE(HasChildCount(PC, 2));
1031 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001032 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "br", SelfClosing()));
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001033 }
1034 }
1035}
1036
1037TEST_F(CommentParserTest, HTML3) {
1038 const char *Sources[] = {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001039 "// <a href",
1040 "// <a href ",
1041 "// <a href>",
1042 "// <a href >",
1043 };
1044
1045 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1046 FullComment *FC = parseString(Sources[i]);
1047 ASSERT_TRUE(HasChildCount(FC, 1));
1048
1049 {
1050 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001051 HTMLStartTagComment *HST;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001052 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1053
1054 ASSERT_TRUE(HasChildCount(PC, 2));
1055 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001056 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", ""));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001057 }
1058 }
1059}
1060
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001061TEST_F(CommentParserTest, HTML4) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001062 const char *Sources[] = {
1063 "// <a href=\"bbb\"",
1064 "// <a href=\"bbb\">",
1065 };
1066
1067 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1068 FullComment *FC = parseString(Sources[i]);
1069 ASSERT_TRUE(HasChildCount(FC, 1));
1070
1071 {
1072 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001073 HTMLStartTagComment *HST;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001074 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1075
1076 ASSERT_TRUE(HasChildCount(PC, 2));
1077 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001078 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "bbb"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001079 }
1080 }
1081}
1082
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001083TEST_F(CommentParserTest, HTML5) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001084 const char *Sources[] = {
1085 "// </a",
1086 "// </a>",
1087 "// </a >"
1088 };
1089
1090 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1091 FullComment *FC = parseString(Sources[i]);
1092 ASSERT_TRUE(HasChildCount(FC, 1));
1093
1094 {
1095 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001096 HTMLEndTagComment *HET;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001097 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1098
1099 ASSERT_TRUE(HasChildCount(PC, 2));
1100 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001101 ASSERT_TRUE(HasHTMLEndTagAt(PC, 1, HET, "a"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001102 }
1103 }
1104}
1105
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001106TEST_F(CommentParserTest, HTML6) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001107 const char *Source =
1108 "// <pre>\n"
1109 "// Aaa\n"
1110 "// Bbb\n"
1111 "// </pre>\n";
1112
1113 FullComment *FC = parseString(Source);
1114 ASSERT_TRUE(HasChildCount(FC, 1));
1115
1116 {
1117 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001118 HTMLStartTagComment *HST;
1119 HTMLEndTagComment *HET;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001120 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1121
1122 ASSERT_TRUE(HasChildCount(PC, 6));
1123 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001124 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "pre", NoAttrs()));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001125 ASSERT_TRUE(HasTextWithNewlineAt(PC, 2, " Aaa"));
1126 ASSERT_TRUE(HasTextWithNewlineAt(PC, 3, " Bbb"));
1127 ASSERT_TRUE(HasTextAt(PC, 4, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001128 ASSERT_TRUE(HasHTMLEndTagAt(PC, 5, HET, "pre"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001129 }
1130}
1131
1132TEST_F(CommentParserTest, VerbatimBlock1) {
1133 const char *Source = "// \\verbatim\\endverbatim\n";
1134
1135 FullComment *FC = parseString(Source);
1136 ASSERT_TRUE(HasChildCount(FC, 2));
1137
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001138 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001139 {
1140 VerbatimBlockComment *VCC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001141 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VCC, "verbatim", "endverbatim",
1142 NoLines()));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001143 }
1144}
1145
1146TEST_F(CommentParserTest, VerbatimBlock2) {
1147 const char *Source = "// \\verbatim Aaa \\endverbatim\n";
1148
1149 FullComment *FC = parseString(Source);
1150 ASSERT_TRUE(HasChildCount(FC, 2));
1151
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001152 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001153 {
1154 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001155 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
1156 Lines(), " Aaa "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001157 }
1158}
1159
1160TEST_F(CommentParserTest, VerbatimBlock3) {
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001161 const char *Source = "// \\verbatim Aaa\n";
1162
1163 FullComment *FC = parseString(Source);
1164 ASSERT_TRUE(HasChildCount(FC, 2));
1165
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001166 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001167 {
1168 VerbatimBlockComment *VBC;
1169 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "",
1170 Lines(), " Aaa"));
1171 }
1172}
1173
1174TEST_F(CommentParserTest, VerbatimBlock4) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001175 const char *Source =
1176 "//\\verbatim\n"
1177 "//\\endverbatim\n";
1178
1179 FullComment *FC = parseString(Source);
1180 ASSERT_TRUE(HasChildCount(FC, 1));
1181
1182 {
1183 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001184 ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", "endverbatim",
1185 NoLines()));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001186 }
1187}
1188
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001189TEST_F(CommentParserTest, VerbatimBlock5) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001190 const char *Sources[] = {
1191 "//\\verbatim\n"
1192 "// Aaa\n"
1193 "//\\endverbatim\n",
1194
1195 "/*\\verbatim\n"
1196 " * Aaa\n"
1197 " *\\endverbatim*/"
1198 };
1199
1200 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1201 FullComment *FC = parseString(Sources[i]);
1202 ASSERT_TRUE(HasChildCount(FC, 1));
1203
1204 {
1205 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001206 ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", "endverbatim",
1207 Lines(), " Aaa"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001208 }
1209 }
1210}
1211
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001212TEST_F(CommentParserTest, VerbatimBlock6) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001213 const char *Sources[] = {
1214 "// \\verbatim\n"
1215 "// Aaa\n"
1216 "// \\endverbatim\n",
1217
1218 "/* \\verbatim\n"
1219 " * Aaa\n"
1220 " * \\endverbatim*/"
1221 };
1222
1223 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1224 FullComment *FC = parseString(Sources[i]);
1225 ASSERT_TRUE(HasChildCount(FC, 2));
1226
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001227 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001228 {
1229 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001230 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
1231 Lines(), " Aaa"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001232 }
1233 }
1234}
1235
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001236TEST_F(CommentParserTest, VerbatimBlock7) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001237 const char *Sources[] = {
1238 "// \\verbatim\n"
1239 "// Aaa\n"
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001240 "// Bbb\n"
1241 "// \\endverbatim\n",
1242
1243 "/* \\verbatim\n"
1244 " * Aaa\n"
1245 " * Bbb\n"
1246 " * \\endverbatim*/"
1247 };
1248
1249 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1250 FullComment *FC = parseString(Sources[i]);
1251 ASSERT_TRUE(HasChildCount(FC, 2));
1252
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001253 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001254 {
1255 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001256 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
1257 Lines(), " Aaa", " Bbb"));
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001258 }
1259 }
1260}
1261
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001262TEST_F(CommentParserTest, VerbatimBlock8) {
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001263 const char *Sources[] = {
1264 "// \\verbatim\n"
1265 "// Aaa\n"
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001266 "//\n"
1267 "// Bbb\n"
1268 "// \\endverbatim\n",
1269
1270 "/* \\verbatim\n"
1271 " * Aaa\n"
1272 " *\n"
1273 " * Bbb\n"
1274 " * \\endverbatim*/"
1275 };
1276 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001277 FullComment *FC = parseString(Sources[i]);
1278 ASSERT_TRUE(HasChildCount(FC, 2));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001279
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001280 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001281 {
1282 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001283 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim"));
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001284 ASSERT_EQ(3U, VBC->getNumLines());
1285 ASSERT_EQ(" Aaa", VBC->getText(0));
1286 ASSERT_EQ("", VBC->getText(1));
1287 ASSERT_EQ(" Bbb", VBC->getText(2));
1288 }
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001289 }
1290}
1291
1292TEST_F(CommentParserTest, VerbatimLine1) {
1293 const char *Sources[] = {
1294 "// \\fn",
1295 "// \\fn\n"
1296 };
1297
1298 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1299 FullComment *FC = parseString(Sources[i]);
1300 ASSERT_TRUE(HasChildCount(FC, 2));
1301
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001302 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001303 {
1304 VerbatimLineComment *VLC;
1305 ASSERT_TRUE(HasVerbatimLineAt(FC, 1, VLC, "fn", ""));
1306 }
1307 }
1308}
1309
1310TEST_F(CommentParserTest, VerbatimLine2) {
1311 const char *Sources[] = {
1312 "/// \\fn void *foo(const char *zzz = \"\\$\");\n//",
1313 "/** \\fn void *foo(const char *zzz = \"\\$\");*/"
1314 };
1315
1316 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1317 FullComment *FC = parseString(Sources[i]);
1318 ASSERT_TRUE(HasChildCount(FC, 2));
1319
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001320 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001321 {
1322 VerbatimLineComment *VLC;
1323 ASSERT_TRUE(HasVerbatimLineAt(FC, 1, VLC, "fn",
1324 " void *foo(const char *zzz = \"\\$\");"));
1325 }
1326 }
1327}
1328
1329} // unnamed namespace
1330
1331} // end namespace comments
1332} // end namespace clang
1333