blob: c6d809ff407643f4bd02c6f948c0957f8851cb06 [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",
763 "// \\param\n"
764 "// [in] aaa Bbb\n",
765 "// \\param [in]\n"
766 "// aaa Bbb\n",
767 "// \\param [in] aaa\n"
768 "// Bbb\n",
769 };
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000770
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000771 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
772 FullComment *FC = parseString(Sources[i]);
773 ASSERT_TRUE(HasChildCount(FC, 2));
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000774
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000775 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
776 {
777 ParamCommandComment *PCC;
778 ParagraphComment *PC;
779 ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
780 ParamCommandComment::In,
781 /* IsDirectionExplicit = */ true,
782 "aaa", PC));
783 ASSERT_TRUE(HasChildCount(PCC, 1));
784 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
785 }
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000786 }
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000787}
788
Dmitri Gribenko3ccc1732012-07-30 16:52:51 +0000789TEST_F(CommentParserTest, ParamCommand4) {
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000790 const char *Sources[] = {
791 "// \\param [out] aaa Bbb\n",
792 "// \\param\n"
793 "// [out] aaa Bbb\n",
794 "// \\param [out]\n"
795 "// aaa Bbb\n",
796 "// \\param [out] aaa\n"
797 "// Bbb\n",
798 };
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000799
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000800 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
801 FullComment *FC = parseString(Sources[i]);
802 ASSERT_TRUE(HasChildCount(FC, 2));
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000803
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000804 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
805 {
806 ParamCommandComment *PCC;
807 ParagraphComment *PC;
808 ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
809 ParamCommandComment::Out,
810 /* IsDirectionExplicit = */ true,
811 "aaa", PC));
812 ASSERT_TRUE(HasChildCount(PCC, 1));
813 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
814 }
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000815 }
816}
817
Dmitri Gribenko3ccc1732012-07-30 16:52:51 +0000818TEST_F(CommentParserTest, ParamCommand5) {
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000819 const char *Sources[] = {
820 "// \\param [in,out] aaa Bbb\n",
Dmitri Gribenko0c43a922012-07-24 18:23:31 +0000821 "// \\param [in, out] aaa Bbb\n",
822 "// \\param [in,\n"
823 "// out] aaa Bbb\n",
824 "// \\param [in,out]\n"
825 "// aaa Bbb\n",
826 "// \\param [in,out] aaa\n"
827 "// Bbb\n"
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000828 };
829
830 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
831 FullComment *FC = parseString(Sources[i]);
832 ASSERT_TRUE(HasChildCount(FC, 2));
833
834 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
835 {
836 ParamCommandComment *PCC;
837 ParagraphComment *PC;
838 ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
839 ParamCommandComment::InOut,
840 /* IsDirectionExplicit = */ true,
841 "aaa", PC));
842 ASSERT_TRUE(HasChildCount(PCC, 1));
843 ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
844 }
845 }
846}
847
Dmitri Gribenko3ccc1732012-07-30 16:52:51 +0000848TEST_F(CommentParserTest, ParamCommand6) {
Dmitri Gribenkofd939162012-07-24 16:10:47 +0000849 const char *Source =
850 "// \\param aaa \\% Bbb \\$ ccc\n";
851
852 FullComment *FC = parseString(Source);
853 ASSERT_TRUE(HasChildCount(FC, 2));
854
855 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
856 {
857 ParamCommandComment *PCC;
858 ParagraphComment *PC;
859 ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
860 ParamCommandComment::In,
861 /* IsDirectionExplicit = */ false,
862 "aaa", PC));
863 ASSERT_TRUE(HasChildCount(PCC, 1));
864
865 ASSERT_TRUE(HasChildCount(PC, 5));
866 ASSERT_TRUE(HasTextAt(PC, 0, " "));
867 ASSERT_TRUE(HasTextAt(PC, 1, "%"));
868 ASSERT_TRUE(HasTextAt(PC, 2, " Bbb "));
869 ASSERT_TRUE(HasTextAt(PC, 3, "$"));
870 ASSERT_TRUE(HasTextAt(PC, 4, " ccc"));
871 }
872}
Dmitri Gribenkoe68c2292012-07-23 23:37:11 +0000873
Dmitri Gribenko96b09862012-07-31 22:37:06 +0000874TEST_F(CommentParserTest, TParamCommand1) {
875 const char *Sources[] = {
876 "// \\tparam aaa Bbb\n",
877 "// \\tparam\n"
878 "// aaa Bbb\n",
879 "// \\tparam \n"
880 "// aaa Bbb\n",
881 "// \\tparam aaa\n"
882 "// Bbb\n"
883 };
884
885 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
886 FullComment *FC = parseString(Sources[i]);
887 ASSERT_TRUE(HasChildCount(FC, 2));
888
889 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
890 {
891 TParamCommandComment *TPCC;
892 ParagraphComment *PC;
893 ASSERT_TRUE(HasTParamCommandAt(FC, 1, TPCC, "tparam",
894 "aaa", PC));
895 ASSERT_TRUE(HasChildCount(TPCC, 1));
896 ASSERT_TRUE(HasParagraphCommentAt(TPCC, 0, " Bbb"));
897 }
898 }
899}
900
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000901TEST_F(CommentParserTest, InlineCommand1) {
902 const char *Source = "// \\c";
903
904 FullComment *FC = parseString(Source);
905 ASSERT_TRUE(HasChildCount(FC, 1));
906
907 {
908 ParagraphComment *PC;
909 InlineCommandComment *ICC;
910 ASSERT_TRUE(GetChildAt(FC, 0, PC));
911
912 ASSERT_TRUE(HasChildCount(PC, 2));
913 ASSERT_TRUE(HasTextAt(PC, 0, " "));
914 ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", NoArgs()));
915 }
916}
917
918TEST_F(CommentParserTest, InlineCommand2) {
919 const char *Source = "// \\c ";
920
921 FullComment *FC = parseString(Source);
922 ASSERT_TRUE(HasChildCount(FC, 1));
923
924 {
925 ParagraphComment *PC;
926 InlineCommandComment *ICC;
927 ASSERT_TRUE(GetChildAt(FC, 0, PC));
928
929 ASSERT_TRUE(HasChildCount(PC, 3));
930 ASSERT_TRUE(HasTextAt(PC, 0, " "));
931 ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", NoArgs()));
932 ASSERT_TRUE(HasTextAt(PC, 2, " "));
933 }
934}
935
936TEST_F(CommentParserTest, InlineCommand3) {
937 const char *Source = "// \\c aaa\n";
938
939 FullComment *FC = parseString(Source);
940 ASSERT_TRUE(HasChildCount(FC, 1));
941
942 {
943 ParagraphComment *PC;
944 InlineCommandComment *ICC;
945 ASSERT_TRUE(GetChildAt(FC, 0, PC));
946
947 ASSERT_TRUE(HasChildCount(PC, 2));
948 ASSERT_TRUE(HasTextAt(PC, 0, " "));
949 ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", "aaa"));
950 }
951}
952
953TEST_F(CommentParserTest, InlineCommand4) {
954 const char *Source = "// \\c aaa bbb";
955
956 FullComment *FC = parseString(Source);
957 ASSERT_TRUE(HasChildCount(FC, 1));
958
959 {
960 ParagraphComment *PC;
961 InlineCommandComment *ICC;
962 ASSERT_TRUE(GetChildAt(FC, 0, PC));
963
964 ASSERT_TRUE(HasChildCount(PC, 3));
965 ASSERT_TRUE(HasTextAt(PC, 0, " "));
966 ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "c", "aaa"));
967 ASSERT_TRUE(HasTextAt(PC, 2, " bbb"));
968 }
969}
970
971TEST_F(CommentParserTest, InlineCommand5) {
972 const char *Source = "// \\unknown aaa\n";
973
974 FullComment *FC = parseString(Source);
975 ASSERT_TRUE(HasChildCount(FC, 1));
976
977 {
978 ParagraphComment *PC;
979 InlineCommandComment *ICC;
980 ASSERT_TRUE(GetChildAt(FC, 0, PC));
981
982 ASSERT_TRUE(HasChildCount(PC, 3));
983 ASSERT_TRUE(HasTextAt(PC, 0, " "));
984 ASSERT_TRUE(HasInlineCommandAt(PC, 1, ICC, "unknown", NoArgs()));
985 ASSERT_TRUE(HasTextAt(PC, 2, " aaa"));
986 }
987}
988
989TEST_F(CommentParserTest, HTML1) {
990 const char *Sources[] = {
991 "// <a",
992 "// <a>",
993 "// <a >"
994 };
995
996 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
997 FullComment *FC = parseString(Sources[i]);
998 ASSERT_TRUE(HasChildCount(FC, 1));
999
1000 {
1001 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001002 HTMLStartTagComment *HST;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001003 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1004
1005 ASSERT_TRUE(HasChildCount(PC, 2));
1006 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001007 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", NoAttrs()));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001008 }
1009 }
1010}
1011
1012TEST_F(CommentParserTest, HTML2) {
1013 const char *Sources[] = {
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001014 "// <br/>",
1015 "// <br />"
1016 };
1017
1018 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1019 FullComment *FC = parseString(Sources[i]);
1020 ASSERT_TRUE(HasChildCount(FC, 1));
1021
1022 {
1023 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001024 HTMLStartTagComment *HST;
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001025 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1026
1027 ASSERT_TRUE(HasChildCount(PC, 2));
1028 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001029 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "br", SelfClosing()));
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001030 }
1031 }
1032}
1033
1034TEST_F(CommentParserTest, HTML3) {
1035 const char *Sources[] = {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001036 "// <a href",
1037 "// <a href ",
1038 "// <a href>",
1039 "// <a href >",
1040 };
1041
1042 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1043 FullComment *FC = parseString(Sources[i]);
1044 ASSERT_TRUE(HasChildCount(FC, 1));
1045
1046 {
1047 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001048 HTMLStartTagComment *HST;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001049 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1050
1051 ASSERT_TRUE(HasChildCount(PC, 2));
1052 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001053 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", ""));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001054 }
1055 }
1056}
1057
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001058TEST_F(CommentParserTest, HTML4) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001059 const char *Sources[] = {
1060 "// <a href=\"bbb\"",
1061 "// <a href=\"bbb\">",
1062 };
1063
1064 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1065 FullComment *FC = parseString(Sources[i]);
1066 ASSERT_TRUE(HasChildCount(FC, 1));
1067
1068 {
1069 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001070 HTMLStartTagComment *HST;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001071 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1072
1073 ASSERT_TRUE(HasChildCount(PC, 2));
1074 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001075 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "bbb"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001076 }
1077 }
1078}
1079
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001080TEST_F(CommentParserTest, HTML5) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001081 const char *Sources[] = {
1082 "// </a",
1083 "// </a>",
1084 "// </a >"
1085 };
1086
1087 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1088 FullComment *FC = parseString(Sources[i]);
1089 ASSERT_TRUE(HasChildCount(FC, 1));
1090
1091 {
1092 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001093 HTMLEndTagComment *HET;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001094 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1095
1096 ASSERT_TRUE(HasChildCount(PC, 2));
1097 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001098 ASSERT_TRUE(HasHTMLEndTagAt(PC, 1, HET, "a"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001099 }
1100 }
1101}
1102
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +00001103TEST_F(CommentParserTest, HTML6) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001104 const char *Source =
1105 "// <pre>\n"
1106 "// Aaa\n"
1107 "// Bbb\n"
1108 "// </pre>\n";
1109
1110 FullComment *FC = parseString(Source);
1111 ASSERT_TRUE(HasChildCount(FC, 1));
1112
1113 {
1114 ParagraphComment *PC;
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001115 HTMLStartTagComment *HST;
1116 HTMLEndTagComment *HET;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001117 ASSERT_TRUE(GetChildAt(FC, 0, PC));
1118
1119 ASSERT_TRUE(HasChildCount(PC, 6));
1120 ASSERT_TRUE(HasTextAt(PC, 0, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001121 ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "pre", NoAttrs()));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001122 ASSERT_TRUE(HasTextWithNewlineAt(PC, 2, " Aaa"));
1123 ASSERT_TRUE(HasTextWithNewlineAt(PC, 3, " Bbb"));
1124 ASSERT_TRUE(HasTextAt(PC, 4, " "));
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +00001125 ASSERT_TRUE(HasHTMLEndTagAt(PC, 5, HET, "pre"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001126 }
1127}
1128
1129TEST_F(CommentParserTest, VerbatimBlock1) {
1130 const char *Source = "// \\verbatim\\endverbatim\n";
1131
1132 FullComment *FC = parseString(Source);
1133 ASSERT_TRUE(HasChildCount(FC, 2));
1134
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001135 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001136 {
1137 VerbatimBlockComment *VCC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001138 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VCC, "verbatim", "endverbatim",
1139 NoLines()));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001140 }
1141}
1142
1143TEST_F(CommentParserTest, VerbatimBlock2) {
1144 const char *Source = "// \\verbatim Aaa \\endverbatim\n";
1145
1146 FullComment *FC = parseString(Source);
1147 ASSERT_TRUE(HasChildCount(FC, 2));
1148
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001149 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001150 {
1151 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001152 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
1153 Lines(), " Aaa "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001154 }
1155}
1156
1157TEST_F(CommentParserTest, VerbatimBlock3) {
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001158 const char *Source = "// \\verbatim Aaa\n";
1159
1160 FullComment *FC = parseString(Source);
1161 ASSERT_TRUE(HasChildCount(FC, 2));
1162
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001163 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001164 {
1165 VerbatimBlockComment *VBC;
1166 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "",
1167 Lines(), " Aaa"));
1168 }
1169}
1170
1171TEST_F(CommentParserTest, VerbatimBlock4) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001172 const char *Source =
1173 "//\\verbatim\n"
1174 "//\\endverbatim\n";
1175
1176 FullComment *FC = parseString(Source);
1177 ASSERT_TRUE(HasChildCount(FC, 1));
1178
1179 {
1180 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001181 ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", "endverbatim",
1182 NoLines()));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001183 }
1184}
1185
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001186TEST_F(CommentParserTest, VerbatimBlock5) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001187 const char *Sources[] = {
1188 "//\\verbatim\n"
1189 "// Aaa\n"
1190 "//\\endverbatim\n",
1191
1192 "/*\\verbatim\n"
1193 " * Aaa\n"
1194 " *\\endverbatim*/"
1195 };
1196
1197 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1198 FullComment *FC = parseString(Sources[i]);
1199 ASSERT_TRUE(HasChildCount(FC, 1));
1200
1201 {
1202 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001203 ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", "endverbatim",
1204 Lines(), " Aaa"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001205 }
1206 }
1207}
1208
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001209TEST_F(CommentParserTest, VerbatimBlock6) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001210 const char *Sources[] = {
1211 "// \\verbatim\n"
1212 "// Aaa\n"
1213 "// \\endverbatim\n",
1214
1215 "/* \\verbatim\n"
1216 " * Aaa\n"
1217 " * \\endverbatim*/"
1218 };
1219
1220 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1221 FullComment *FC = parseString(Sources[i]);
1222 ASSERT_TRUE(HasChildCount(FC, 2));
1223
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001224 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001225 {
1226 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001227 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
1228 Lines(), " Aaa"));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001229 }
1230 }
1231}
1232
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001233TEST_F(CommentParserTest, VerbatimBlock7) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001234 const char *Sources[] = {
1235 "// \\verbatim\n"
1236 "// Aaa\n"
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001237 "// Bbb\n"
1238 "// \\endverbatim\n",
1239
1240 "/* \\verbatim\n"
1241 " * Aaa\n"
1242 " * Bbb\n"
1243 " * \\endverbatim*/"
1244 };
1245
1246 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1247 FullComment *FC = parseString(Sources[i]);
1248 ASSERT_TRUE(HasChildCount(FC, 2));
1249
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001250 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001251 {
1252 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001253 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim",
1254 Lines(), " Aaa", " Bbb"));
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001255 }
1256 }
1257}
1258
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001259TEST_F(CommentParserTest, VerbatimBlock8) {
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001260 const char *Sources[] = {
1261 "// \\verbatim\n"
1262 "// Aaa\n"
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001263 "//\n"
1264 "// Bbb\n"
1265 "// \\endverbatim\n",
1266
1267 "/* \\verbatim\n"
1268 " * Aaa\n"
1269 " *\n"
1270 " * Bbb\n"
1271 " * \\endverbatim*/"
1272 };
1273 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001274 FullComment *FC = parseString(Sources[i]);
1275 ASSERT_TRUE(HasChildCount(FC, 2));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001276
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001277 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001278 {
1279 VerbatimBlockComment *VBC;
Dmitri Gribenko9f08f492012-07-20 20:18:53 +00001280 ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim"));
Dmitri Gribenko64da4e52012-07-18 23:01:58 +00001281 ASSERT_EQ(3U, VBC->getNumLines());
1282 ASSERT_EQ(" Aaa", VBC->getText(0));
1283 ASSERT_EQ("", VBC->getText(1));
1284 ASSERT_EQ(" Bbb", VBC->getText(2));
1285 }
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001286 }
1287}
1288
1289TEST_F(CommentParserTest, VerbatimLine1) {
1290 const char *Sources[] = {
1291 "// \\fn",
1292 "// \\fn\n"
1293 };
1294
1295 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1296 FullComment *FC = parseString(Sources[i]);
1297 ASSERT_TRUE(HasChildCount(FC, 2));
1298
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001299 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001300 {
1301 VerbatimLineComment *VLC;
1302 ASSERT_TRUE(HasVerbatimLineAt(FC, 1, VLC, "fn", ""));
1303 }
1304 }
1305}
1306
1307TEST_F(CommentParserTest, VerbatimLine2) {
1308 const char *Sources[] = {
1309 "/// \\fn void *foo(const char *zzz = \"\\$\");\n//",
1310 "/** \\fn void *foo(const char *zzz = \"\\$\");*/"
1311 };
1312
1313 for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
1314 FullComment *FC = parseString(Sources[i]);
1315 ASSERT_TRUE(HasChildCount(FC, 2));
1316
Dmitri Gribenkodebd16f2012-07-23 23:09:32 +00001317 ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001318 {
1319 VerbatimLineComment *VLC;
1320 ASSERT_TRUE(HasVerbatimLineAt(FC, 1, VLC, "fn",
1321 " void *foo(const char *zzz = \"\\$\");"));
1322 }
1323 }
1324}
1325
1326} // unnamed namespace
1327
1328} // end namespace comments
1329} // end namespace clang
1330