1 | //===- unittests/AST/CommentParser.cpp ------ Comment parser tests --------===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "clang/AST/CommentParser.h" |
10 | #include "clang/AST/Comment.h" |
11 | #include "clang/AST/CommentCommandTraits.h" |
12 | #include "clang/AST/CommentLexer.h" |
13 | #include "clang/AST/CommentSema.h" |
14 | #include "clang/Basic/CommentOptions.h" |
15 | #include "clang/Basic/Diagnostic.h" |
16 | #include "clang/Basic/DiagnosticOptions.h" |
17 | #include "clang/Basic/FileManager.h" |
18 | #include "clang/Basic/SourceManager.h" |
19 | #include "llvm/ADT/STLExtras.h" |
20 | #include "llvm/Support/Allocator.h" |
21 | #include "gtest/gtest.h" |
22 | |
23 | using namespace llvm; |
24 | using namespace clang; |
25 | |
26 | namespace clang { |
27 | namespace comments { |
28 | |
29 | namespace { |
30 | |
31 | const bool MY_DEBUG = true; |
32 | |
33 | class CommentParserTest : public ::testing::Test { |
34 | protected: |
35 | CommentParserTest() |
36 | : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()), |
37 | Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()), |
38 | SourceMgr(Diags, FileMgr), Traits(Allocator, CommentOptions()) {} |
39 | |
40 | FileSystemOptions FileMgrOpts; |
41 | FileManager FileMgr; |
42 | IntrusiveRefCntPtr<DiagnosticIDs> DiagID; |
43 | DiagnosticOptions DiagOpts; |
44 | DiagnosticsEngine Diags; |
45 | SourceManager SourceMgr; |
46 | llvm::BumpPtrAllocator Allocator; |
47 | CommandTraits Traits; |
48 | |
49 | FullComment *parseString(const char *Source); |
50 | }; |
51 | |
52 | FullComment *CommentParserTest::parseString(const char *Source) { |
53 | std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(InputData: Source); |
54 | FileID File = SourceMgr.createFileID(Buffer: std::move(Buf)); |
55 | SourceLocation Begin = SourceMgr.getLocForStartOfFile(FID: File); |
56 | |
57 | Lexer L(Allocator, Diags, Traits, Begin, Source, Source + strlen(Source)); |
58 | |
59 | Sema S(Allocator, SourceMgr, Diags, Traits, /*PP=*/ nullptr); |
60 | Parser P(L, S, Allocator, SourceMgr, Diags, Traits); |
61 | FullComment *FC = P.parseFullComment(); |
62 | |
63 | if (MY_DEBUG) { |
64 | llvm::errs() << "=== Source:\n"<< Source << "\n=== AST:\n"; |
65 | FC->dump(); |
66 | } |
67 | |
68 | Token Tok; |
69 | L.lex(T&: Tok); |
70 | if (Tok.is(K: tok::eof)) |
71 | return FC; |
72 | else |
73 | return nullptr; |
74 | } |
75 | |
76 | ::testing::AssertionResult HasChildCount(const Comment *C, size_t Count) { |
77 | if (!C) |
78 | return ::testing::AssertionFailure() << "Comment is NULL"; |
79 | |
80 | if (Count != C->child_count()) |
81 | return ::testing::AssertionFailure() |
82 | << "Count = "<< Count |
83 | << ", child_count = "<< C->child_count(); |
84 | |
85 | return ::testing::AssertionSuccess(); |
86 | } |
87 | |
88 | template <typename T> |
89 | ::testing::AssertionResult GetChildAt(const Comment *C, |
90 | size_t Idx, |
91 | T *&Child) { |
92 | if (!C) |
93 | return ::testing::AssertionFailure() << "Comment is NULL"; |
94 | |
95 | if (Idx >= C->child_count()) |
96 | return ::testing::AssertionFailure() |
97 | << "Idx out of range. Idx = "<< Idx |
98 | << ", child_count = "<< C->child_count(); |
99 | |
100 | Comment::child_iterator I = C->child_begin() + Idx; |
101 | Comment *CommentChild = *I; |
102 | if (!CommentChild) |
103 | return ::testing::AssertionFailure() << "Child is NULL"; |
104 | |
105 | Child = dyn_cast<T>(CommentChild); |
106 | if (!Child) |
107 | return ::testing::AssertionFailure() |
108 | << "Child is not of requested type, but a " |
109 | << CommentChild->getCommentKindName(); |
110 | |
111 | return ::testing::AssertionSuccess(); |
112 | } |
113 | |
114 | ::testing::AssertionResult HasTextAt(const Comment *C, |
115 | size_t Idx, |
116 | StringRef Text) { |
117 | TextComment *TC; |
118 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: TC); |
119 | if (!AR) |
120 | return AR; |
121 | |
122 | StringRef ActualText = TC->getText(); |
123 | if (ActualText != Text) |
124 | return ::testing::AssertionFailure() |
125 | << "TextComment has text \""<< ActualText.str() << "\", " |
126 | "expected \""<< Text.str() << "\""; |
127 | |
128 | if (TC->hasTrailingNewline()) |
129 | return ::testing::AssertionFailure() |
130 | << "TextComment has a trailing newline"; |
131 | |
132 | return ::testing::AssertionSuccess(); |
133 | } |
134 | |
135 | ::testing::AssertionResult HasTextWithNewlineAt(const Comment *C, |
136 | size_t Idx, |
137 | StringRef Text) { |
138 | TextComment *TC; |
139 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: TC); |
140 | if (!AR) |
141 | return AR; |
142 | |
143 | StringRef ActualText = TC->getText(); |
144 | if (ActualText != Text) |
145 | return ::testing::AssertionFailure() |
146 | << "TextComment has text \""<< ActualText.str() << "\", " |
147 | "expected \""<< Text.str() << "\""; |
148 | |
149 | if (!TC->hasTrailingNewline()) |
150 | return ::testing::AssertionFailure() |
151 | << "TextComment has no trailing newline"; |
152 | |
153 | return ::testing::AssertionSuccess(); |
154 | } |
155 | |
156 | ::testing::AssertionResult HasBlockCommandAt(const Comment *C, |
157 | const CommandTraits &Traits, |
158 | size_t Idx, |
159 | BlockCommandComment *&BCC, |
160 | StringRef Name, |
161 | ParagraphComment *&Paragraph) { |
162 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: BCC); |
163 | if (!AR) |
164 | return AR; |
165 | |
166 | StringRef ActualName = BCC->getCommandName(Traits); |
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 |
178 | HasParamCommandAt(const Comment *C, const CommandTraits &Traits, size_t Idx, |
179 | ParamCommandComment *&PCC, StringRef CommandName, |
180 | ParamCommandPassDirection Direction, bool IsDirectionExplicit, |
181 | StringRef ParamName, ParagraphComment *&Paragraph) { |
182 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: PCC); |
183 | if (!AR) |
184 | return AR; |
185 | |
186 | StringRef ActualCommandName = PCC->getCommandName(Traits); |
187 | if (ActualCommandName != CommandName) |
188 | return ::testing::AssertionFailure() |
189 | << "ParamCommandComment has name \""<< ActualCommandName.str() << "\", " |
190 | "expected \""<< CommandName.str() << "\""; |
191 | |
192 | if (PCC->getDirection() != Direction) |
193 | return ::testing::AssertionFailure() |
194 | << "ParamCommandComment has direction " |
195 | << llvm::to_underlying(E: PCC->getDirection()) << ", expected " |
196 | << llvm::to_underlying(E: Direction); |
197 | |
198 | if (PCC->isDirectionExplicit() != IsDirectionExplicit) |
199 | return ::testing::AssertionFailure() |
200 | << "ParamCommandComment has " |
201 | << (PCC->isDirectionExplicit() ? "explicit": "implicit") |
202 | << " direction, " |
203 | "expected "<< (IsDirectionExplicit ? "explicit": "implicit"); |
204 | |
205 | if (!ParamName.empty() && !PCC->hasParamName()) |
206 | return ::testing::AssertionFailure() |
207 | << "ParamCommandComment has no parameter name"; |
208 | |
209 | StringRef ActualParamName = PCC->hasParamName() ? PCC->getParamNameAsWritten() : ""; |
210 | if (ActualParamName != ParamName) |
211 | return ::testing::AssertionFailure() |
212 | << "ParamCommandComment has parameter name \""<< ActualParamName.str() |
213 | << "\", " |
214 | "expected \""<< ParamName.str() << "\""; |
215 | |
216 | Paragraph = PCC->getParagraph(); |
217 | |
218 | return ::testing::AssertionSuccess(); |
219 | } |
220 | |
221 | ::testing::AssertionResult HasTParamCommandAt( |
222 | const Comment *C, |
223 | const CommandTraits &Traits, |
224 | size_t Idx, |
225 | TParamCommandComment *&TPCC, |
226 | StringRef CommandName, |
227 | StringRef ParamName, |
228 | ParagraphComment *&Paragraph) { |
229 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: TPCC); |
230 | if (!AR) |
231 | return AR; |
232 | |
233 | StringRef ActualCommandName = TPCC->getCommandName(Traits); |
234 | if (ActualCommandName != CommandName) |
235 | return ::testing::AssertionFailure() |
236 | << "TParamCommandComment has name \""<< ActualCommandName.str() << "\", " |
237 | "expected \""<< CommandName.str() << "\""; |
238 | |
239 | if (!ParamName.empty() && !TPCC->hasParamName()) |
240 | return ::testing::AssertionFailure() |
241 | << "TParamCommandComment has no parameter name"; |
242 | |
243 | StringRef ActualParamName = TPCC->hasParamName() ? TPCC->getParamNameAsWritten() : ""; |
244 | if (ActualParamName != ParamName) |
245 | return ::testing::AssertionFailure() |
246 | << "TParamCommandComment has parameter name \""<< ActualParamName.str() |
247 | << "\", " |
248 | "expected \""<< ParamName.str() << "\""; |
249 | |
250 | Paragraph = TPCC->getParagraph(); |
251 | |
252 | return ::testing::AssertionSuccess(); |
253 | } |
254 | |
255 | ::testing::AssertionResult HasInlineCommandAt(const Comment *C, |
256 | const CommandTraits &Traits, |
257 | size_t Idx, |
258 | InlineCommandComment *&ICC, |
259 | StringRef Name) { |
260 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: ICC); |
261 | if (!AR) |
262 | return AR; |
263 | |
264 | StringRef ActualName = ICC->getCommandName(Traits); |
265 | if (ActualName != Name) |
266 | return ::testing::AssertionFailure() |
267 | << "InlineCommandComment has name \""<< ActualName.str() << "\", " |
268 | "expected \""<< Name.str() << "\""; |
269 | |
270 | return ::testing::AssertionSuccess(); |
271 | } |
272 | |
273 | struct NoArgs {}; |
274 | |
275 | ::testing::AssertionResult HasInlineCommandAt(const Comment *C, |
276 | const CommandTraits &Traits, |
277 | size_t Idx, |
278 | InlineCommandComment *&ICC, |
279 | StringRef Name, |
280 | NoArgs) { |
281 | ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name); |
282 | if (!AR) |
283 | return AR; |
284 | |
285 | if (ICC->getNumArgs() != 0) |
286 | return ::testing::AssertionFailure() |
287 | << "InlineCommandComment has "<< ICC->getNumArgs() << " arg(s), " |
288 | "expected 0"; |
289 | |
290 | return ::testing::AssertionSuccess(); |
291 | } |
292 | |
293 | ::testing::AssertionResult HasInlineCommandAt(const Comment *C, |
294 | const CommandTraits &Traits, |
295 | size_t Idx, |
296 | InlineCommandComment *&ICC, |
297 | StringRef Name, |
298 | StringRef Arg) { |
299 | ::testing::AssertionResult AR = HasInlineCommandAt(C, Traits, Idx, ICC, Name); |
300 | if (!AR) |
301 | return AR; |
302 | |
303 | if (ICC->getNumArgs() != 1) |
304 | return ::testing::AssertionFailure() |
305 | << "InlineCommandComment has "<< ICC->getNumArgs() << " arg(s), " |
306 | "expected 1"; |
307 | |
308 | StringRef ActualArg = ICC->getArgText(Idx: 0); |
309 | if (ActualArg != Arg) |
310 | return ::testing::AssertionFailure() |
311 | << "InlineCommandComment has argument \""<< ActualArg.str() << "\", " |
312 | "expected \""<< Arg.str() << "\""; |
313 | |
314 | return ::testing::AssertionSuccess(); |
315 | } |
316 | |
317 | ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C, |
318 | size_t Idx, |
319 | HTMLStartTagComment *&HST, |
320 | StringRef TagName) { |
321 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: HST); |
322 | if (!AR) |
323 | return AR; |
324 | |
325 | StringRef ActualTagName = HST->getTagName(); |
326 | if (ActualTagName != TagName) |
327 | return ::testing::AssertionFailure() |
328 | << "HTMLStartTagComment has name \""<< ActualTagName.str() << "\", " |
329 | "expected \""<< TagName.str() << "\""; |
330 | |
331 | return ::testing::AssertionSuccess(); |
332 | } |
333 | |
334 | struct SelfClosing {}; |
335 | |
336 | ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C, |
337 | size_t Idx, |
338 | HTMLStartTagComment *&HST, |
339 | StringRef TagName, |
340 | SelfClosing) { |
341 | ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName); |
342 | if (!AR) |
343 | return AR; |
344 | |
345 | if (!HST->isSelfClosing()) |
346 | return ::testing::AssertionFailure() |
347 | << "HTMLStartTagComment is not self-closing"; |
348 | |
349 | return ::testing::AssertionSuccess(); |
350 | } |
351 | |
352 | |
353 | struct NoAttrs {}; |
354 | |
355 | ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C, |
356 | size_t Idx, |
357 | HTMLStartTagComment *&HST, |
358 | StringRef TagName, |
359 | NoAttrs) { |
360 | ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName); |
361 | if (!AR) |
362 | return AR; |
363 | |
364 | if (HST->isSelfClosing()) |
365 | return ::testing::AssertionFailure() |
366 | << "HTMLStartTagComment is self-closing"; |
367 | |
368 | if (HST->getNumAttrs() != 0) |
369 | return ::testing::AssertionFailure() |
370 | << "HTMLStartTagComment has "<< HST->getNumAttrs() << " attr(s), " |
371 | "expected 0"; |
372 | |
373 | return ::testing::AssertionSuccess(); |
374 | } |
375 | |
376 | ::testing::AssertionResult HasHTMLStartTagAt(const Comment *C, |
377 | size_t Idx, |
378 | HTMLStartTagComment *&HST, |
379 | StringRef TagName, |
380 | StringRef AttrName, |
381 | StringRef AttrValue) { |
382 | ::testing::AssertionResult AR = HasHTMLStartTagAt(C, Idx, HST, TagName); |
383 | if (!AR) |
384 | return AR; |
385 | |
386 | if (HST->isSelfClosing()) |
387 | return ::testing::AssertionFailure() |
388 | << "HTMLStartTagComment is self-closing"; |
389 | |
390 | if (HST->getNumAttrs() != 1) |
391 | return ::testing::AssertionFailure() |
392 | << "HTMLStartTagComment has "<< HST->getNumAttrs() << " attr(s), " |
393 | "expected 1"; |
394 | |
395 | StringRef ActualName = HST->getAttr(Idx: 0).Name; |
396 | if (ActualName != AttrName) |
397 | return ::testing::AssertionFailure() |
398 | << "HTMLStartTagComment has attr \""<< ActualName.str() << "\", " |
399 | "expected \""<< AttrName.str() << "\""; |
400 | |
401 | StringRef ActualValue = HST->getAttr(Idx: 0).Value; |
402 | if (ActualValue != AttrValue) |
403 | return ::testing::AssertionFailure() |
404 | << "HTMLStartTagComment has attr value \""<< ActualValue.str() << "\", " |
405 | "expected \""<< AttrValue.str() << "\""; |
406 | |
407 | return ::testing::AssertionSuccess(); |
408 | } |
409 | |
410 | ::testing::AssertionResult HasHTMLEndTagAt(const Comment *C, |
411 | size_t Idx, |
412 | HTMLEndTagComment *&HET, |
413 | StringRef TagName) { |
414 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: HET); |
415 | if (!AR) |
416 | return AR; |
417 | |
418 | StringRef ActualTagName = HET->getTagName(); |
419 | if (ActualTagName != TagName) |
420 | return ::testing::AssertionFailure() |
421 | << "HTMLEndTagComment has name \""<< ActualTagName.str() << "\", " |
422 | "expected \""<< TagName.str() << "\""; |
423 | |
424 | return ::testing::AssertionSuccess(); |
425 | } |
426 | |
427 | ::testing::AssertionResult HasParagraphCommentAt(const Comment *C, |
428 | size_t Idx, |
429 | StringRef Text) { |
430 | ParagraphComment *PC; |
431 | |
432 | { |
433 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: PC); |
434 | if (!AR) |
435 | return AR; |
436 | } |
437 | |
438 | { |
439 | ::testing::AssertionResult AR = HasChildCount(PC, 1); |
440 | if (!AR) |
441 | return AR; |
442 | } |
443 | |
444 | { |
445 | ::testing::AssertionResult AR = HasTextAt(PC, 0, Text); |
446 | if (!AR) |
447 | return AR; |
448 | } |
449 | |
450 | return ::testing::AssertionSuccess(); |
451 | } |
452 | |
453 | ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C, |
454 | const CommandTraits &Traits, |
455 | size_t Idx, |
456 | VerbatimBlockComment *&VBC, |
457 | StringRef Name, |
458 | StringRef CloseName) { |
459 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: VBC); |
460 | if (!AR) |
461 | return AR; |
462 | |
463 | StringRef ActualName = VBC->getCommandName(Traits); |
464 | if (ActualName != Name) |
465 | return ::testing::AssertionFailure() |
466 | << "VerbatimBlockComment has name \""<< ActualName.str() << "\", " |
467 | "expected \""<< Name.str() << "\""; |
468 | |
469 | StringRef ActualCloseName = VBC->getCloseName(); |
470 | if (ActualCloseName != CloseName) |
471 | return ::testing::AssertionFailure() |
472 | << "VerbatimBlockComment has closing command name \"" |
473 | << ActualCloseName.str() << "\", " |
474 | "expected \""<< CloseName.str() << "\""; |
475 | |
476 | return ::testing::AssertionSuccess(); |
477 | } |
478 | |
479 | struct NoLines {}; |
480 | struct Lines {}; |
481 | |
482 | ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C, |
483 | const CommandTraits &Traits, |
484 | size_t Idx, |
485 | VerbatimBlockComment *&VBC, |
486 | StringRef Name, |
487 | StringRef CloseName, |
488 | NoLines) { |
489 | ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name, |
490 | CloseName); |
491 | if (!AR) |
492 | return AR; |
493 | |
494 | if (VBC->getNumLines() != 0) |
495 | return ::testing::AssertionFailure() |
496 | << "VerbatimBlockComment has "<< VBC->getNumLines() << " lines(s), " |
497 | "expected 0"; |
498 | |
499 | return ::testing::AssertionSuccess(); |
500 | } |
501 | |
502 | ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C, |
503 | const CommandTraits &Traits, |
504 | size_t Idx, |
505 | VerbatimBlockComment *&VBC, |
506 | StringRef Name, |
507 | StringRef CloseName, |
508 | Lines, |
509 | StringRef Line0) { |
510 | ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name, |
511 | CloseName); |
512 | if (!AR) |
513 | return AR; |
514 | |
515 | if (VBC->getNumLines() != 1) |
516 | return ::testing::AssertionFailure() |
517 | << "VerbatimBlockComment has "<< VBC->getNumLines() << " lines(s), " |
518 | "expected 1"; |
519 | |
520 | StringRef ActualLine0 = VBC->getText(LineIdx: 0); |
521 | if (ActualLine0 != Line0) |
522 | return ::testing::AssertionFailure() |
523 | << "VerbatimBlockComment has lines[0] \""<< ActualLine0.str() << "\", " |
524 | "expected \""<< Line0.str() << "\""; |
525 | |
526 | return ::testing::AssertionSuccess(); |
527 | } |
528 | |
529 | ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C, |
530 | const CommandTraits &Traits, |
531 | size_t Idx, |
532 | VerbatimBlockComment *&VBC, |
533 | StringRef Name, |
534 | StringRef CloseName, |
535 | Lines, |
536 | StringRef Line0, |
537 | StringRef Line1) { |
538 | ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Traits, Idx, VBC, Name, |
539 | CloseName); |
540 | if (!AR) |
541 | return AR; |
542 | |
543 | if (VBC->getNumLines() != 2) |
544 | return ::testing::AssertionFailure() |
545 | << "VerbatimBlockComment has "<< VBC->getNumLines() << " lines(s), " |
546 | "expected 2"; |
547 | |
548 | StringRef ActualLine0 = VBC->getText(LineIdx: 0); |
549 | if (ActualLine0 != Line0) |
550 | return ::testing::AssertionFailure() |
551 | << "VerbatimBlockComment has lines[0] \""<< ActualLine0.str() << "\", " |
552 | "expected \""<< Line0.str() << "\""; |
553 | |
554 | StringRef ActualLine1 = VBC->getText(LineIdx: 1); |
555 | if (ActualLine1 != Line1) |
556 | return ::testing::AssertionFailure() |
557 | << "VerbatimBlockComment has lines[1] \""<< ActualLine1.str() << "\", " |
558 | "expected \""<< Line1.str() << "\""; |
559 | |
560 | return ::testing::AssertionSuccess(); |
561 | } |
562 | |
563 | ::testing::AssertionResult HasVerbatimLineAt(const Comment *C, |
564 | const CommandTraits &Traits, |
565 | size_t Idx, |
566 | VerbatimLineComment *&VLC, |
567 | StringRef Name, |
568 | StringRef Text) { |
569 | ::testing::AssertionResult AR = GetChildAt(C, Idx, Child&: VLC); |
570 | if (!AR) |
571 | return AR; |
572 | |
573 | StringRef ActualName = VLC->getCommandName(Traits); |
574 | if (ActualName != Name) |
575 | return ::testing::AssertionFailure() |
576 | << "VerbatimLineComment has name \""<< ActualName.str() << "\", " |
577 | "expected \""<< Name.str() << "\""; |
578 | |
579 | StringRef ActualText = VLC->getText(); |
580 | if (ActualText != Text) |
581 | return ::testing::AssertionFailure() |
582 | << "VerbatimLineComment has text \""<< ActualText.str() << "\", " |
583 | "expected \""<< Text.str() << "\""; |
584 | |
585 | return ::testing::AssertionSuccess(); |
586 | } |
587 | |
588 | |
589 | TEST_F(CommentParserTest, Basic1) { |
590 | const char *Source = "//"; |
591 | |
592 | FullComment *FC = parseString(Source); |
593 | ASSERT_TRUE(HasChildCount(FC, 0)); |
594 | } |
595 | |
596 | TEST_F(CommentParserTest, Basic2) { |
597 | const char *Source = "// Meow"; |
598 | |
599 | FullComment *FC = parseString(Source); |
600 | ASSERT_TRUE(HasChildCount(FC, 1)); |
601 | |
602 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Meow")); |
603 | } |
604 | |
605 | TEST_F(CommentParserTest, Basic3) { |
606 | const char *Source = |
607 | "// Aaa\n" |
608 | "// Bbb"; |
609 | |
610 | FullComment *FC = parseString(Source); |
611 | ASSERT_TRUE(HasChildCount(FC, 1)); |
612 | |
613 | { |
614 | ParagraphComment *PC; |
615 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
616 | |
617 | ASSERT_TRUE(HasChildCount(PC, 2)); |
618 | ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa")); |
619 | ASSERT_TRUE(HasTextAt(PC, 1, " Bbb")); |
620 | } |
621 | } |
622 | |
623 | TEST_F(CommentParserTest, ParagraphSplitting1) { |
624 | const char *Sources[] = { |
625 | ("// Aaa\n" |
626 | "//\n" |
627 | "// Bbb"), |
628 | |
629 | ("// Aaa\n" |
630 | "// \n" |
631 | "// Bbb"), |
632 | |
633 | ("// Aaa\n" |
634 | "//\t\n" |
635 | "// Bbb"), |
636 | |
637 | ("// Aaa\n" |
638 | "//\n" |
639 | "//\n" |
640 | "// Bbb"), |
641 | |
642 | ("/**\n" |
643 | " Aaa\n" |
644 | "\n" |
645 | " Bbb\n" |
646 | "*/"), |
647 | |
648 | ("/**\n" |
649 | " Aaa\n" |
650 | " \n" |
651 | " Bbb\n" |
652 | "*/"), |
653 | |
654 | ("/**\n" |
655 | " Aaa\n" |
656 | "\t \n" |
657 | " Bbb\n" |
658 | "*/"), |
659 | }; |
660 | |
661 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
662 | FullComment *FC = parseString(Sources[i]); |
663 | ASSERT_TRUE(HasChildCount(FC, 2)); |
664 | |
665 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " Aaa")); |
666 | ASSERT_TRUE(HasParagraphCommentAt(FC, 1, " Bbb")); |
667 | } |
668 | } |
669 | |
670 | TEST_F(CommentParserTest, Paragraph1) { |
671 | const char *Source = |
672 | "// \\brief Aaa\n" |
673 | "//\n" |
674 | "// Bbb"; |
675 | |
676 | FullComment *FC = parseString(Source); |
677 | ASSERT_TRUE(HasChildCount(FC, 3)); |
678 | |
679 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
680 | { |
681 | BlockCommandComment *BCC; |
682 | ParagraphComment *PC; |
683 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC)); |
684 | |
685 | ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Aaa")); |
686 | } |
687 | ASSERT_TRUE(HasParagraphCommentAt(FC, 2, " Bbb")); |
688 | } |
689 | |
690 | TEST_F(CommentParserTest, Paragraph2) { |
691 | const char *Source = "// \\brief \\author"; |
692 | |
693 | FullComment *FC = parseString(Source); |
694 | ASSERT_TRUE(HasChildCount(FC, 3)); |
695 | |
696 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
697 | { |
698 | BlockCommandComment *BCC; |
699 | ParagraphComment *PC; |
700 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC)); |
701 | |
702 | ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " ")); |
703 | } |
704 | { |
705 | BlockCommandComment *BCC; |
706 | ParagraphComment *PC; |
707 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC)); |
708 | |
709 | ASSERT_TRUE(GetChildAt(BCC, 0, PC)); |
710 | ASSERT_TRUE(HasChildCount(PC, 0)); |
711 | } |
712 | } |
713 | |
714 | TEST_F(CommentParserTest, Paragraph3) { |
715 | const char *Source = |
716 | "// \\brief Aaa\n" |
717 | "// Bbb \\author\n" |
718 | "// Ccc"; |
719 | |
720 | FullComment *FC = parseString(Source); |
721 | ASSERT_TRUE(HasChildCount(FC, 3)); |
722 | |
723 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
724 | { |
725 | BlockCommandComment *BCC; |
726 | ParagraphComment *PC; |
727 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "brief", PC)); |
728 | |
729 | ASSERT_TRUE(GetChildAt(BCC, 0, PC)); |
730 | ASSERT_TRUE(HasChildCount(PC, 2)); |
731 | ASSERT_TRUE(HasTextWithNewlineAt(PC, 0, " Aaa")); |
732 | ASSERT_TRUE(HasTextAt(PC, 1, " Bbb ")); |
733 | } |
734 | { |
735 | BlockCommandComment *BCC; |
736 | ParagraphComment *PC; |
737 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "author", PC)); |
738 | |
739 | ASSERT_TRUE(HasParagraphCommentAt(BCC, 0, " Ccc")); |
740 | } |
741 | } |
742 | |
743 | TEST_F(CommentParserTest, ParamCommand1) { |
744 | const char *Source = "// \\param aaa"; |
745 | |
746 | FullComment *FC = parseString(Source); |
747 | ASSERT_TRUE(HasChildCount(FC, 2)); |
748 | |
749 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
750 | { |
751 | ParamCommandComment *PCC; |
752 | ParagraphComment *PC; |
753 | ASSERT_TRUE(HasParamCommandAt( |
754 | FC, Traits, 1, PCC, "param", ParamCommandPassDirection::In, |
755 | /* IsDirectionExplicit = */ false, "aaa", PC)); |
756 | ASSERT_TRUE(HasChildCount(PCC, 1)); |
757 | ASSERT_TRUE(HasChildCount(PC, 0)); |
758 | } |
759 | } |
760 | |
761 | TEST_F(CommentParserTest, ParamCommand2) { |
762 | const char *Source = "// \\param\\brief"; |
763 | |
764 | FullComment *FC = parseString(Source); |
765 | ASSERT_TRUE(HasChildCount(FC, 3)); |
766 | |
767 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
768 | { |
769 | ParamCommandComment *PCC; |
770 | ParagraphComment *PC; |
771 | ASSERT_TRUE(HasParamCommandAt(FC, Traits, 1, PCC, "param", |
772 | ParamCommandPassDirection::In, |
773 | /* IsDirectionExplicit = */ false, "", PC)); |
774 | ASSERT_TRUE(HasChildCount(PCC, 1)); |
775 | ASSERT_TRUE(HasChildCount(PC, 0)); |
776 | } |
777 | { |
778 | BlockCommandComment *BCC; |
779 | ParagraphComment *PC; |
780 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC)); |
781 | ASSERT_TRUE(HasChildCount(PC, 0)); |
782 | } |
783 | } |
784 | |
785 | TEST_F(CommentParserTest, ParamCommand3) { |
786 | const char *Sources[] = { |
787 | "// \\param aaa Bbb\n", |
788 | ("// \\param\n" |
789 | "// aaa Bbb\n"), |
790 | ("// \\param \n" |
791 | "// aaa Bbb\n"), |
792 | ("// \\param aaa\n" |
793 | "// Bbb\n") |
794 | }; |
795 | |
796 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
797 | FullComment *FC = parseString(Sources[i]); |
798 | ASSERT_TRUE(HasChildCount(FC, 2)); |
799 | |
800 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
801 | { |
802 | ParamCommandComment *PCC; |
803 | ParagraphComment *PC; |
804 | ASSERT_TRUE(HasParamCommandAt( |
805 | FC, Traits, 1, PCC, "param", ParamCommandPassDirection::In, |
806 | /* IsDirectionExplicit = */ false, "aaa", PC)); |
807 | ASSERT_TRUE(HasChildCount(PCC, 1)); |
808 | ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); |
809 | } |
810 | } |
811 | } |
812 | |
813 | TEST_F(CommentParserTest, ParamCommand4) { |
814 | const char *Sources[] = { |
815 | "// \\param [in] aaa Bbb\n", |
816 | "// \\param[in] aaa Bbb\n", |
817 | ("// \\param\n" |
818 | "// [in] aaa Bbb\n"), |
819 | ("// \\param [in]\n" |
820 | "// aaa Bbb\n"), |
821 | ("// \\param [in] aaa\n" |
822 | "// Bbb\n"), |
823 | }; |
824 | |
825 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
826 | FullComment *FC = parseString(Sources[i]); |
827 | ASSERT_TRUE(HasChildCount(FC, 2)); |
828 | |
829 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
830 | { |
831 | ParamCommandComment *PCC; |
832 | ParagraphComment *PC; |
833 | ASSERT_TRUE(HasParamCommandAt( |
834 | FC, Traits, 1, PCC, "param", ParamCommandPassDirection::In, |
835 | /* IsDirectionExplicit = */ true, "aaa", PC)); |
836 | ASSERT_TRUE(HasChildCount(PCC, 1)); |
837 | ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); |
838 | } |
839 | } |
840 | } |
841 | |
842 | TEST_F(CommentParserTest, ParamCommand5) { |
843 | const char *Sources[] = { |
844 | "// \\param [out] aaa Bbb\n", |
845 | "// \\param[out] aaa Bbb\n", |
846 | ("// \\param\n" |
847 | "// [out] aaa Bbb\n"), |
848 | ("// \\param [out]\n" |
849 | "// aaa Bbb\n"), |
850 | ("// \\param [out] aaa\n" |
851 | "// Bbb\n"), |
852 | }; |
853 | |
854 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
855 | FullComment *FC = parseString(Sources[i]); |
856 | ASSERT_TRUE(HasChildCount(FC, 2)); |
857 | |
858 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
859 | { |
860 | ParamCommandComment *PCC; |
861 | ParagraphComment *PC; |
862 | ASSERT_TRUE(HasParamCommandAt( |
863 | FC, Traits, 1, PCC, "param", ParamCommandPassDirection::Out, |
864 | /* IsDirectionExplicit = */ true, "aaa", PC)); |
865 | ASSERT_TRUE(HasChildCount(PCC, 1)); |
866 | ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); |
867 | } |
868 | } |
869 | } |
870 | |
871 | TEST_F(CommentParserTest, ParamCommand6) { |
872 | const char *Sources[] = { |
873 | "// \\param [in,out] aaa Bbb\n", |
874 | "// \\param[in,out] aaa Bbb\n", |
875 | "// \\param [in, out] aaa Bbb\n", |
876 | "// \\param [in,\n" |
877 | "// out] aaa Bbb\n", |
878 | "// \\param [in,out]\n" |
879 | "// aaa Bbb\n", |
880 | "// \\param [in,out] aaa\n" |
881 | "// Bbb\n" |
882 | }; |
883 | |
884 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
885 | FullComment *FC = parseString(Sources[i]); |
886 | ASSERT_TRUE(HasChildCount(FC, 2)); |
887 | |
888 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
889 | { |
890 | ParamCommandComment *PCC; |
891 | ParagraphComment *PC; |
892 | ASSERT_TRUE(HasParamCommandAt( |
893 | FC, Traits, 1, PCC, "param", ParamCommandPassDirection::InOut, |
894 | /* IsDirectionExplicit = */ true, "aaa", PC)); |
895 | ASSERT_TRUE(HasChildCount(PCC, 1)); |
896 | ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb")); |
897 | } |
898 | } |
899 | } |
900 | |
901 | TEST_F(CommentParserTest, ParamCommand7) { |
902 | const char *Source = |
903 | "// \\param aaa \\% Bbb \\$ ccc\n"; |
904 | |
905 | FullComment *FC = parseString(Source); |
906 | ASSERT_TRUE(HasChildCount(FC, 2)); |
907 | |
908 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
909 | { |
910 | ParamCommandComment *PCC; |
911 | ParagraphComment *PC; |
912 | ASSERT_TRUE(HasParamCommandAt( |
913 | FC, Traits, 1, PCC, "param", ParamCommandPassDirection::In, |
914 | /* IsDirectionExplicit = */ false, "aaa", PC)); |
915 | ASSERT_TRUE(HasChildCount(PCC, 1)); |
916 | |
917 | ASSERT_TRUE(HasChildCount(PC, 5)); |
918 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
919 | ASSERT_TRUE(HasTextAt(PC, 1, "%")); |
920 | ASSERT_TRUE(HasTextAt(PC, 2, " Bbb ")); |
921 | ASSERT_TRUE(HasTextAt(PC, 3, "$")); |
922 | ASSERT_TRUE(HasTextAt(PC, 4, " ccc")); |
923 | } |
924 | } |
925 | |
926 | TEST_F(CommentParserTest, TParamCommand1) { |
927 | const char *Sources[] = { |
928 | "// \\tparam aaa Bbb\n", |
929 | "// \\tparam\n" |
930 | "// aaa Bbb\n", |
931 | "// \\tparam \n" |
932 | "// aaa Bbb\n", |
933 | "// \\tparam aaa\n" |
934 | "// Bbb\n" |
935 | }; |
936 | |
937 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
938 | FullComment *FC = parseString(Sources[i]); |
939 | ASSERT_TRUE(HasChildCount(FC, 2)); |
940 | |
941 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
942 | { |
943 | TParamCommandComment *TPCC; |
944 | ParagraphComment *PC; |
945 | ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam", |
946 | "aaa", PC)); |
947 | ASSERT_TRUE(HasChildCount(TPCC, 1)); |
948 | ASSERT_TRUE(HasParagraphCommentAt(TPCC, 0, " Bbb")); |
949 | } |
950 | } |
951 | } |
952 | |
953 | TEST_F(CommentParserTest, TParamCommand2) { |
954 | const char *Source = "// \\tparam\\brief"; |
955 | |
956 | FullComment *FC = parseString(Source); |
957 | ASSERT_TRUE(HasChildCount(FC, 3)); |
958 | |
959 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
960 | { |
961 | TParamCommandComment *TPCC; |
962 | ParagraphComment *PC; |
963 | ASSERT_TRUE(HasTParamCommandAt(FC, Traits, 1, TPCC, "tparam", "", PC)); |
964 | ASSERT_TRUE(HasChildCount(TPCC, 1)); |
965 | ASSERT_TRUE(HasChildCount(PC, 0)); |
966 | } |
967 | { |
968 | BlockCommandComment *BCC; |
969 | ParagraphComment *PC; |
970 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 2, BCC, "brief", PC)); |
971 | ASSERT_TRUE(HasChildCount(PC, 0)); |
972 | } |
973 | } |
974 | |
975 | |
976 | TEST_F(CommentParserTest, InlineCommand1) { |
977 | const char *Source = "// \\c"; |
978 | |
979 | FullComment *FC = parseString(Source); |
980 | ASSERT_TRUE(HasChildCount(FC, 1)); |
981 | |
982 | { |
983 | ParagraphComment *PC; |
984 | InlineCommandComment *ICC; |
985 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
986 | |
987 | ASSERT_TRUE(HasChildCount(PC, 2)); |
988 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
989 | ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs())); |
990 | } |
991 | } |
992 | |
993 | TEST_F(CommentParserTest, InlineCommand2) { |
994 | const char *Source = "// \\c "; |
995 | |
996 | FullComment *FC = parseString(Source); |
997 | ASSERT_TRUE(HasChildCount(FC, 1)); |
998 | |
999 | { |
1000 | ParagraphComment *PC; |
1001 | InlineCommandComment *ICC; |
1002 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
1003 | |
1004 | ASSERT_TRUE(HasChildCount(PC, 3)); |
1005 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
1006 | ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", NoArgs())); |
1007 | ASSERT_TRUE(HasTextAt(PC, 2, " ")); |
1008 | } |
1009 | } |
1010 | |
1011 | TEST_F(CommentParserTest, InlineCommand3) { |
1012 | const char *Source = "// \\c aaa\n"; |
1013 | |
1014 | FullComment *FC = parseString(Source); |
1015 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1016 | |
1017 | { |
1018 | ParagraphComment *PC; |
1019 | InlineCommandComment *ICC; |
1020 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
1021 | |
1022 | ASSERT_TRUE(HasChildCount(PC, 2)); |
1023 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
1024 | ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa")); |
1025 | } |
1026 | } |
1027 | |
1028 | TEST_F(CommentParserTest, InlineCommand4) { |
1029 | const char *Source = "// \\c aaa bbb"; |
1030 | |
1031 | FullComment *FC = parseString(Source); |
1032 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1033 | |
1034 | { |
1035 | ParagraphComment *PC; |
1036 | InlineCommandComment *ICC; |
1037 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
1038 | |
1039 | ASSERT_TRUE(HasChildCount(PC, 3)); |
1040 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
1041 | ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "c", "aaa")); |
1042 | ASSERT_TRUE(HasTextAt(PC, 2, " bbb")); |
1043 | } |
1044 | } |
1045 | |
1046 | TEST_F(CommentParserTest, InlineCommand5) { |
1047 | const char *Source = "// \\unknown aaa\n"; |
1048 | |
1049 | FullComment *FC = parseString(Source); |
1050 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1051 | |
1052 | { |
1053 | ParagraphComment *PC; |
1054 | InlineCommandComment *ICC; |
1055 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
1056 | |
1057 | ASSERT_TRUE(HasChildCount(PC, 3)); |
1058 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
1059 | ASSERT_TRUE(HasInlineCommandAt(PC, Traits, 1, ICC, "unknown", NoArgs())); |
1060 | ASSERT_TRUE(HasTextAt(PC, 2, " aaa")); |
1061 | } |
1062 | } |
1063 | |
1064 | TEST_F(CommentParserTest, HTML1) { |
1065 | const char *Sources[] = { |
1066 | "// <a", |
1067 | "// <a>", |
1068 | "// <a >", |
1069 | "// <a\n// >", |
1070 | }; |
1071 | |
1072 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1073 | FullComment *FC = parseString(Sources[i]); |
1074 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1075 | |
1076 | { |
1077 | ParagraphComment *PC; |
1078 | HTMLStartTagComment *HST; |
1079 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
1080 | |
1081 | ASSERT_TRUE(HasChildCount(PC, 2)); |
1082 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
1083 | ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", NoAttrs())); |
1084 | } |
1085 | } |
1086 | } |
1087 | |
1088 | TEST_F(CommentParserTest, HTML2) { |
1089 | const char *Sources[] = { |
1090 | "// <br/>", |
1091 | "// <br />", |
1092 | "// <br \n// />", |
1093 | }; |
1094 | |
1095 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1096 | FullComment *FC = parseString(Sources[i]); |
1097 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1098 | |
1099 | { |
1100 | ParagraphComment *PC; |
1101 | HTMLStartTagComment *HST; |
1102 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
1103 | |
1104 | ASSERT_TRUE(HasChildCount(PC, 2)); |
1105 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
1106 | ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "br", SelfClosing())); |
1107 | } |
1108 | } |
1109 | } |
1110 | |
1111 | TEST_F(CommentParserTest, HTML3) { |
1112 | const char *Sources[] = { |
1113 | "// <a href", "// <a href ", "// <a href>", |
1114 | "// <a href >", "// <a \n// href >", |
1115 | }; |
1116 | |
1117 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1118 | FullComment *FC = parseString(Sources[i]); |
1119 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1120 | |
1121 | { |
1122 | ParagraphComment *PC; |
1123 | HTMLStartTagComment *HST; |
1124 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
1125 | |
1126 | ASSERT_TRUE(HasChildCount(PC, 2)); |
1127 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
1128 | ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "")); |
1129 | } |
1130 | } |
1131 | } |
1132 | |
1133 | TEST_F(CommentParserTest, HTML4) { |
1134 | const char *Sources[] = { |
1135 | "// <a href=\"bbb\"", |
1136 | "// <a href=\"bbb\">", |
1137 | "// <a \n// href=\"bbb\">", |
1138 | }; |
1139 | |
1140 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1141 | FullComment *FC = parseString(Sources[i]); |
1142 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1143 | |
1144 | { |
1145 | ParagraphComment *PC; |
1146 | HTMLStartTagComment *HST; |
1147 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
1148 | |
1149 | ASSERT_TRUE(HasChildCount(PC, 2)); |
1150 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
1151 | ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "a", "href", "bbb")); |
1152 | } |
1153 | } |
1154 | } |
1155 | |
1156 | TEST_F(CommentParserTest, HTML5) { |
1157 | const char *Sources[] = { |
1158 | "// </a", |
1159 | "// </a>", |
1160 | "// </a >" |
1161 | }; |
1162 | |
1163 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1164 | FullComment *FC = parseString(Sources[i]); |
1165 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1166 | |
1167 | { |
1168 | ParagraphComment *PC; |
1169 | HTMLEndTagComment *HET; |
1170 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
1171 | |
1172 | ASSERT_TRUE(HasChildCount(PC, 2)); |
1173 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
1174 | ASSERT_TRUE(HasHTMLEndTagAt(PC, 1, HET, "a")); |
1175 | } |
1176 | } |
1177 | } |
1178 | |
1179 | TEST_F(CommentParserTest, HTML6) { |
1180 | const char *Source = |
1181 | "// <pre>\n" |
1182 | "// Aaa\n" |
1183 | "// Bbb\n" |
1184 | "// </pre>\n"; |
1185 | |
1186 | FullComment *FC = parseString(Source); |
1187 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1188 | |
1189 | { |
1190 | ParagraphComment *PC; |
1191 | HTMLStartTagComment *HST; |
1192 | HTMLEndTagComment *HET; |
1193 | ASSERT_TRUE(GetChildAt(FC, 0, PC)); |
1194 | |
1195 | ASSERT_TRUE(HasChildCount(PC, 6)); |
1196 | ASSERT_TRUE(HasTextAt(PC, 0, " ")); |
1197 | ASSERT_TRUE(HasHTMLStartTagAt(PC, 1, HST, "pre", NoAttrs())); |
1198 | ASSERT_TRUE(HasTextWithNewlineAt(PC, 2, " Aaa")); |
1199 | ASSERT_TRUE(HasTextWithNewlineAt(PC, 3, " Bbb")); |
1200 | ASSERT_TRUE(HasTextAt(PC, 4, " ")); |
1201 | ASSERT_TRUE(HasHTMLEndTagAt(PC, 5, HET, "pre")); |
1202 | } |
1203 | } |
1204 | |
1205 | TEST_F(CommentParserTest, VerbatimBlock1) { |
1206 | const char *Source = "// \\verbatim\\endverbatim\n"; |
1207 | |
1208 | FullComment *FC = parseString(Source); |
1209 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1210 | |
1211 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1212 | { |
1213 | VerbatimBlockComment *VCC; |
1214 | ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VCC, |
1215 | "verbatim", "endverbatim", |
1216 | NoLines())); |
1217 | } |
1218 | } |
1219 | |
1220 | TEST_F(CommentParserTest, VerbatimBlock2) { |
1221 | const char *Source = "// \\verbatim Aaa \\endverbatim\n"; |
1222 | |
1223 | FullComment *FC = parseString(Source); |
1224 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1225 | |
1226 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1227 | { |
1228 | VerbatimBlockComment *VBC; |
1229 | ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, |
1230 | "verbatim", "endverbatim", |
1231 | Lines(), " Aaa ")); |
1232 | } |
1233 | } |
1234 | |
1235 | TEST_F(CommentParserTest, VerbatimBlock3) { |
1236 | const char *Source = "// \\verbatim Aaa\n"; |
1237 | |
1238 | FullComment *FC = parseString(Source); |
1239 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1240 | |
1241 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1242 | { |
1243 | VerbatimBlockComment *VBC; |
1244 | ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, "verbatim", "", |
1245 | Lines(), " Aaa")); |
1246 | } |
1247 | } |
1248 | |
1249 | TEST_F(CommentParserTest, VerbatimBlock4) { |
1250 | const char *Source = |
1251 | "//\\verbatim\n" |
1252 | "//\\endverbatim\n"; |
1253 | |
1254 | FullComment *FC = parseString(Source); |
1255 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1256 | |
1257 | { |
1258 | VerbatimBlockComment *VBC; |
1259 | ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC, |
1260 | "verbatim", "endverbatim", |
1261 | NoLines())); |
1262 | } |
1263 | } |
1264 | |
1265 | TEST_F(CommentParserTest, VerbatimBlock5) { |
1266 | const char *Sources[] = { |
1267 | "//\\verbatim\n" |
1268 | "// Aaa\n" |
1269 | "//\\endverbatim\n", |
1270 | |
1271 | "/*\\verbatim\n" |
1272 | " * Aaa\n" |
1273 | " *\\endverbatim*/" |
1274 | }; |
1275 | |
1276 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1277 | FullComment *FC = parseString(Sources[i]); |
1278 | ASSERT_TRUE(HasChildCount(FC, 1)); |
1279 | |
1280 | { |
1281 | VerbatimBlockComment *VBC; |
1282 | ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 0, VBC, |
1283 | "verbatim", "endverbatim", |
1284 | Lines(), " Aaa")); |
1285 | } |
1286 | } |
1287 | } |
1288 | |
1289 | TEST_F(CommentParserTest, VerbatimBlock6) { |
1290 | const char *Sources[] = { |
1291 | "// \\verbatim\n" |
1292 | "// Aaa\n" |
1293 | "// \\endverbatim\n", |
1294 | |
1295 | "/* \\verbatim\n" |
1296 | " * Aaa\n" |
1297 | " * \\endverbatim*/" |
1298 | }; |
1299 | |
1300 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1301 | FullComment *FC = parseString(Sources[i]); |
1302 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1303 | |
1304 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1305 | { |
1306 | VerbatimBlockComment *VBC; |
1307 | ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, |
1308 | "verbatim", "endverbatim", |
1309 | Lines(), " Aaa")); |
1310 | } |
1311 | } |
1312 | } |
1313 | |
1314 | TEST_F(CommentParserTest, VerbatimBlock7) { |
1315 | const char *Sources[] = { |
1316 | "// \\verbatim\n" |
1317 | "// Aaa\n" |
1318 | "// Bbb\n" |
1319 | "// \\endverbatim\n", |
1320 | |
1321 | "/* \\verbatim\n" |
1322 | " * Aaa\n" |
1323 | " * Bbb\n" |
1324 | " * \\endverbatim*/" |
1325 | }; |
1326 | |
1327 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1328 | FullComment *FC = parseString(Sources[i]); |
1329 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1330 | |
1331 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1332 | { |
1333 | VerbatimBlockComment *VBC; |
1334 | ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, |
1335 | "verbatim", "endverbatim", |
1336 | Lines(), " Aaa", " Bbb")); |
1337 | } |
1338 | } |
1339 | } |
1340 | |
1341 | TEST_F(CommentParserTest, VerbatimBlock8) { |
1342 | const char *Sources[] = { |
1343 | "// \\verbatim\n" |
1344 | "// Aaa\n" |
1345 | "//\n" |
1346 | "// Bbb\n" |
1347 | "// \\endverbatim\n", |
1348 | |
1349 | "/* \\verbatim\n" |
1350 | " * Aaa\n" |
1351 | " *\n" |
1352 | " * Bbb\n" |
1353 | " * \\endverbatim*/" |
1354 | }; |
1355 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1356 | FullComment *FC = parseString(Sources[i]); |
1357 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1358 | |
1359 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1360 | { |
1361 | VerbatimBlockComment *VBC; |
1362 | ASSERT_TRUE(HasVerbatimBlockAt(FC, Traits, 1, VBC, |
1363 | "verbatim", "endverbatim")); |
1364 | ASSERT_EQ(3U, VBC->getNumLines()); |
1365 | ASSERT_EQ(" Aaa", VBC->getText(0)); |
1366 | ASSERT_EQ("", VBC->getText(1)); |
1367 | ASSERT_EQ(" Bbb", VBC->getText(2)); |
1368 | } |
1369 | } |
1370 | } |
1371 | |
1372 | TEST_F(CommentParserTest, VerbatimLine1) { |
1373 | const char *Sources[] = { |
1374 | "// \\fn", |
1375 | "// \\fn\n" |
1376 | }; |
1377 | |
1378 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1379 | FullComment *FC = parseString(Sources[i]); |
1380 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1381 | |
1382 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1383 | { |
1384 | VerbatimLineComment *VLC; |
1385 | ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn", "")); |
1386 | } |
1387 | } |
1388 | } |
1389 | |
1390 | TEST_F(CommentParserTest, VerbatimLine2) { |
1391 | const char *Sources[] = { |
1392 | "/// \\fn void *foo(const char *zzz = \"\\$\");\n//", |
1393 | "/** \\fn void *foo(const char *zzz = \"\\$\");*/" |
1394 | }; |
1395 | |
1396 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1397 | FullComment *FC = parseString(Sources[i]); |
1398 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1399 | |
1400 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1401 | { |
1402 | VerbatimLineComment *VLC; |
1403 | ASSERT_TRUE(HasVerbatimLineAt(FC, Traits, 1, VLC, "fn", |
1404 | " void *foo(const char *zzz = \"\\$\");")); |
1405 | } |
1406 | } |
1407 | } |
1408 | |
1409 | TEST_F(CommentParserTest, Deprecated) { |
1410 | const char *Sources[] = { |
1411 | "/** @deprecated*/", |
1412 | "/// @deprecated\n" |
1413 | }; |
1414 | |
1415 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1416 | FullComment *FC = parseString(Sources[i]); |
1417 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1418 | |
1419 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1420 | { |
1421 | BlockCommandComment *BCC; |
1422 | ParagraphComment *PC; |
1423 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "deprecated", PC)); |
1424 | ASSERT_TRUE(HasChildCount(PC, 0)); |
1425 | } |
1426 | } |
1427 | } |
1428 | |
1429 | TEST_F(CommentParserTest, ThrowsCommandHasArg1) { |
1430 | const char *Sources[] = { |
1431 | "/// @throws int This function throws an integer", |
1432 | ("/// @throws\n" |
1433 | "/// int This function throws an integer"), |
1434 | ("/// @throws \n" |
1435 | "/// int This function throws an integer"), |
1436 | ("/// @throws\n" |
1437 | "/// int\n" |
1438 | "/// This function throws an integer"), |
1439 | ("/// @throws \n" |
1440 | "/// int \n" |
1441 | "/// This function throws an integer"), |
1442 | }; |
1443 | |
1444 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1445 | FullComment *FC = parseString(Sources[i]); |
1446 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1447 | |
1448 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1449 | { |
1450 | BlockCommandComment *BCC; |
1451 | ParagraphComment *PC; |
1452 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC)); |
1453 | ASSERT_TRUE(HasChildCount(PC, 1)); |
1454 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1455 | ASSERT_TRUE(BCC->getArgText(0) == "int"); |
1456 | } |
1457 | } |
1458 | } |
1459 | |
1460 | TEST_F(CommentParserTest, ThrowsCommandHasArg2) { |
1461 | const char *Sources[] = { |
1462 | "/// @throws int** This function throws a double pointer to an integer", |
1463 | }; |
1464 | |
1465 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1466 | FullComment *FC = parseString(Sources[i]); |
1467 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1468 | |
1469 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1470 | { |
1471 | BlockCommandComment *BCC; |
1472 | ParagraphComment *PC; |
1473 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC)); |
1474 | ASSERT_TRUE(HasChildCount(PC, 1)); |
1475 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1476 | ASSERT_TRUE(BCC->getArgText(0) == "int**"); |
1477 | } |
1478 | } |
1479 | } |
1480 | |
1481 | TEST_F(CommentParserTest, ThrowsCommandHasArg3) { |
1482 | const char *Sources[] = { |
1483 | "/// @throws Error<T> error of type Error<T>", |
1484 | }; |
1485 | |
1486 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1487 | FullComment *FC = parseString(Sources[i]); |
1488 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1489 | |
1490 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1491 | { |
1492 | BlockCommandComment *BCC; |
1493 | ParagraphComment *PC; |
1494 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC)); |
1495 | ASSERT_TRUE(HasChildCount(PC, 3)); // Extra children because <T> is parsed |
1496 | // as a series of TextComments |
1497 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1498 | ASSERT_TRUE(BCC->getArgText(0) == "Error<T>"); |
1499 | } |
1500 | } |
1501 | } |
1502 | |
1503 | TEST_F(CommentParserTest, ThrowsCommandHasArg4) { |
1504 | const char *Sources[] = { |
1505 | "/// @throws Error<Container<T>> nested templates", |
1506 | }; |
1507 | |
1508 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1509 | FullComment *FC = parseString(Sources[i]); |
1510 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1511 | |
1512 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1513 | { |
1514 | BlockCommandComment *BCC; |
1515 | ParagraphComment *PC; |
1516 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC)); |
1517 | ASSERT_TRUE(HasChildCount(PC, 1)); |
1518 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1519 | ASSERT_TRUE(BCC->getArgText(0) == "Error<Container<T>>"); |
1520 | } |
1521 | } |
1522 | } |
1523 | |
1524 | TEST_F(CommentParserTest, ThrowsCommandHasArg5) { |
1525 | const char *Sources[] = { |
1526 | "/// @throws Error<Ts...> variadic templates", |
1527 | }; |
1528 | |
1529 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1530 | FullComment *FC = parseString(Sources[i]); |
1531 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1532 | |
1533 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1534 | { |
1535 | BlockCommandComment *BCC; |
1536 | ParagraphComment *PC; |
1537 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC)); |
1538 | ASSERT_TRUE(HasChildCount(PC, 1)); |
1539 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1540 | ASSERT_TRUE(BCC->getArgText(0) == "Error<Ts...>"); |
1541 | } |
1542 | } |
1543 | } |
1544 | |
1545 | TEST_F(CommentParserTest, ThrowsCommandHasArg6) { |
1546 | const char *Sources[] = { |
1547 | "/// @throws Foo<(1 > 0)> typo1", |
1548 | }; |
1549 | |
1550 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1551 | FullComment *FC = parseString(Sources[i]); |
1552 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1553 | |
1554 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1555 | { |
1556 | BlockCommandComment *BCC; |
1557 | ParagraphComment *PC; |
1558 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC)); |
1559 | ASSERT_TRUE(HasChildCount(PC, 1)); |
1560 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1561 | ASSERT_TRUE(BCC->getArgText(0) == "Foo<(1 >"); |
1562 | } |
1563 | } |
1564 | } |
1565 | |
1566 | // No matter the number of (unmatched) opening brackets, no type is parsed. |
1567 | TEST_F(CommentParserTest, ThrowsCommandHasArg7) { |
1568 | const char *Sources[] = { |
1569 | "/// @throws Foo<", |
1570 | "/// @throws Foo<<<", |
1571 | "/// @throws Foo<<<<<<<", |
1572 | "/// @throws Foo<\n", |
1573 | "/// @throws Foo<<<\n", |
1574 | "/// @throws Foo<<<<<<<\n", |
1575 | }; |
1576 | |
1577 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1578 | FullComment *FC = parseString(Sources[i]); |
1579 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1580 | |
1581 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1582 | { |
1583 | BlockCommandComment *BCC; |
1584 | ParagraphComment *PC; |
1585 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC)); |
1586 | ASSERT_TRUE(HasChildCount(PC, 0)); |
1587 | ASSERT_TRUE(BCC->getNumArgs() == 0); |
1588 | } |
1589 | } |
1590 | } |
1591 | |
1592 | // Types with a non-matching closing bracket are parsed as if they are a type |
1593 | TEST_F(CommentParserTest, ThrowsCommandHasArg8) { |
1594 | const char *Sources[] = { |
1595 | "/// @throws Foo>", |
1596 | "/// @throws Foo>\n", |
1597 | }; |
1598 | |
1599 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1600 | FullComment *FC = parseString(Sources[i]); |
1601 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1602 | |
1603 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1604 | { |
1605 | BlockCommandComment *BCC; |
1606 | ParagraphComment *PC; |
1607 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC)); |
1608 | ASSERT_TRUE(HasChildCount(PC, 0)); |
1609 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1610 | ASSERT_TRUE(BCC->getArgText(0) == "Foo>"); |
1611 | } |
1612 | } |
1613 | } |
1614 | |
1615 | // Everying up until the end of the paragraph comment will be |
1616 | // eaten up if the template sequence is unterminated (i.e. number of |
1617 | // opening and closing brackets is not equal). |
1618 | TEST_F(CommentParserTest, ThrowsCommandHasArg9) { |
1619 | const char *Sources[] = { |
1620 | "/// @throws Foo<Bar<t>\n" |
1621 | "/// Aaa\n" |
1622 | "///\n" |
1623 | "/// Bbb\n" |
1624 | }; |
1625 | |
1626 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1627 | FullComment *FC = parseString(Sources[i]); |
1628 | ASSERT_TRUE(HasChildCount(FC, 3)); |
1629 | |
1630 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1631 | { |
1632 | BlockCommandComment *BCC; |
1633 | ParagraphComment *PC; |
1634 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "throws", PC)); |
1635 | ASSERT_TRUE(HasChildCount(PC, 0)); |
1636 | ASSERT_TRUE(BCC->getNumArgs() == 0); |
1637 | } |
1638 | } |
1639 | } |
1640 | |
1641 | TEST_F(CommentParserTest, ParCommandHasArg1) { |
1642 | const char *Sources[] = { |
1643 | "/// @par Paragraph header:", "/// @par Paragraph header:\n", |
1644 | "/// @par Paragraph header:\r\n", "/// @par Paragraph header:\n\r", |
1645 | "/** @par Paragraph header:*/", |
1646 | }; |
1647 | |
1648 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1649 | FullComment *FC = parseString(Sources[i]); |
1650 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1651 | |
1652 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1653 | { |
1654 | BlockCommandComment *BCC; |
1655 | ParagraphComment *PC; |
1656 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "par", PC)); |
1657 | ASSERT_TRUE(HasChildCount(PC, 0)); |
1658 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1659 | ASSERT_TRUE(BCC->getArgText(0) == "Paragraph header:"); |
1660 | } |
1661 | } |
1662 | } |
1663 | |
1664 | TEST_F(CommentParserTest, ParCommandHasArg2) { |
1665 | const char *Sources[] = { |
1666 | "/// @par Paragraph header: ", "/// @par Paragraph header: \n", |
1667 | "/// @par Paragraph header: \r\n", "/// @par Paragraph header: \n\r", |
1668 | "/** @par Paragraph header: */", |
1669 | }; |
1670 | |
1671 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1672 | FullComment *FC = parseString(Sources[i]); |
1673 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1674 | |
1675 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1676 | { |
1677 | BlockCommandComment *BCC; |
1678 | ParagraphComment *PC; |
1679 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "par", PC)); |
1680 | ASSERT_TRUE(HasChildCount(PC, 0)); |
1681 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1682 | ASSERT_TRUE(BCC->getArgText(0) == "Paragraph header: "); |
1683 | } |
1684 | } |
1685 | } |
1686 | |
1687 | TEST_F(CommentParserTest, ParCommandHasArg3) { |
1688 | const char *Sources[] = { |
1689 | ("/// @par Paragraph header:\n" |
1690 | "/// Paragraph body"), |
1691 | ("/// @par Paragraph header:\r\n" |
1692 | "/// Paragraph body"), |
1693 | ("/// @par Paragraph header:\n\r" |
1694 | "/// Paragraph body"), |
1695 | }; |
1696 | |
1697 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1698 | FullComment *FC = parseString(Sources[i]); |
1699 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1700 | |
1701 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1702 | { |
1703 | BlockCommandComment *BCC; |
1704 | ParagraphComment *PC; |
1705 | TextComment *TC; |
1706 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "par", PC)); |
1707 | ASSERT_TRUE(HasChildCount(PC, 1)); |
1708 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1709 | ASSERT_TRUE(BCC->getArgText(0) == "Paragraph header:"); |
1710 | ASSERT_TRUE(GetChildAt(PC, 0, TC)); |
1711 | ASSERT_TRUE(TC->getText() == " Paragraph body"); |
1712 | } |
1713 | } |
1714 | } |
1715 | |
1716 | TEST_F(CommentParserTest, ParCommandHasArg4) { |
1717 | const char *Sources[] = { |
1718 | ("/// @par Paragraph header:\n" |
1719 | "/// Paragraph body1\n" |
1720 | "/// Paragraph body2"), |
1721 | ("/// @par Paragraph header:\r\n" |
1722 | "/// Paragraph body1\n" |
1723 | "/// Paragraph body2"), |
1724 | ("/// @par Paragraph header:\n\r" |
1725 | "/// Paragraph body1\n" |
1726 | "/// Paragraph body2"), |
1727 | }; |
1728 | |
1729 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1730 | FullComment *FC = parseString(Sources[i]); |
1731 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1732 | |
1733 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1734 | { |
1735 | BlockCommandComment *BCC; |
1736 | ParagraphComment *PC; |
1737 | TextComment *TC; |
1738 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "par", PC)); |
1739 | ASSERT_TRUE(HasChildCount(PC, 2)); |
1740 | ASSERT_TRUE(BCC->getNumArgs() == 1); |
1741 | ASSERT_TRUE(BCC->getArgText(0) == "Paragraph header:"); |
1742 | ASSERT_TRUE(GetChildAt(PC, 0, TC)); |
1743 | ASSERT_TRUE(TC->getText() == " Paragraph body1"); |
1744 | ASSERT_TRUE(GetChildAt(PC, 1, TC)); |
1745 | ASSERT_TRUE(TC->getText() == " Paragraph body2"); |
1746 | } |
1747 | } |
1748 | } |
1749 | |
1750 | TEST_F(CommentParserTest, ParCommandHasArg5) { |
1751 | const char *Sources[] = { |
1752 | ("/// @par \n" |
1753 | "/// Paragraphs with no text before newline have no heading"), |
1754 | ("/// @par \r\n" |
1755 | "/// Paragraphs with no text before newline have no heading"), |
1756 | ("/// @par \n\r" |
1757 | "/// Paragraphs with no text before newline have no heading"), |
1758 | }; |
1759 | |
1760 | for (size_t i = 0, e = std::size(Sources); i != e; i++) { |
1761 | FullComment *FC = parseString(Sources[i]); |
1762 | ASSERT_TRUE(HasChildCount(FC, 2)); |
1763 | |
1764 | ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " ")); |
1765 | { |
1766 | BlockCommandComment *BCC; |
1767 | ParagraphComment *PC; |
1768 | TextComment *TC; |
1769 | ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "par", PC)); |
1770 | ASSERT_TRUE(HasChildCount(PC, 1)); |
1771 | ASSERT_TRUE(BCC->getNumArgs() == 0); |
1772 | ASSERT_TRUE(GetChildAt(PC, 0, TC)); |
1773 | ASSERT_TRUE(TC->getText() == |
1774 | "Paragraphs with no text before newline have no heading"); |
1775 | } |
1776 | } |
1777 | } |
1778 | |
1779 | } // unnamed namespace |
1780 | |
1781 | } // end namespace comments |
1782 | } // end namespace clang |
1783 |
Definitions
- MY_DEBUG
- CommentParserTest
- CommentParserTest
- parseString
- HasChildCount
- GetChildAt
- HasTextAt
- HasTextWithNewlineAt
- HasBlockCommandAt
- HasParamCommandAt
- HasTParamCommandAt
- HasInlineCommandAt
- NoArgs
- HasInlineCommandAt
- HasInlineCommandAt
- HasHTMLStartTagAt
- SelfClosing
- HasHTMLStartTagAt
- NoAttrs
- HasHTMLStartTagAt
- HasHTMLStartTagAt
- HasHTMLEndTagAt
- HasParagraphCommentAt
- HasVerbatimBlockAt
- NoLines
- Lines
- HasVerbatimBlockAt
- HasVerbatimBlockAt
- HasVerbatimBlockAt
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more