1 | #include "ClangDocTest.h" |
2 | #include "Generators.h" |
3 | #include "Representation.h" |
4 | #include "gtest/gtest.h" |
5 | |
6 | namespace clang { |
7 | namespace doc { |
8 | |
9 | static std::unique_ptr<Generator> getJSONGenerator() { |
10 | auto G = doc::findGeneratorByName(Format: "json" ); |
11 | if (!G) |
12 | return nullptr; |
13 | return std::move(G.get()); |
14 | } |
15 | |
16 | TEST(JSONGeneratorTest, emitRecordJSON) { |
17 | RecordInfo I; |
18 | I.Name = "Foo" ; |
19 | // FIXME: FullName is not emitted correctly. |
20 | I.FullName = "" ; |
21 | I.IsTypeDef = false; |
22 | I.Namespace.emplace_back(Args: EmptySID, Args: "GlobalNamespace" , Args: InfoType::IT_namespace); |
23 | I.Path = "GlobalNamespace" ; |
24 | I.DefLoc = Location(1, 1, "main.cpp" ); |
25 | I.TagType = TagTypeKind::Class; |
26 | |
27 | I.Template = TemplateInfo(); |
28 | I.Template->Params.emplace_back(args: "class T" ); |
29 | |
30 | I.Children.Enums.emplace_back(); |
31 | I.Children.Enums.back().Name = "Color" ; |
32 | I.Children.Enums.back().Scoped = false; |
33 | I.Children.Enums.back().Members.emplace_back(); |
34 | I.Children.Enums.back().Members.back().Name = "RED" ; |
35 | I.Children.Enums.back().Members.back().Value = "0" ; |
36 | |
37 | I.Members.emplace_back(Args: TypeInfo("int" ), Args: "X" , Args: AccessSpecifier::AS_protected); |
38 | |
39 | I.Bases.emplace_back(args: EmptySID, args: "F" , args: "path/to/F" , args: true, |
40 | args: AccessSpecifier::AS_public, args: true); |
41 | I.Bases.back().Children.Functions.emplace_back(); |
42 | I.Bases.back().Children.Functions.back().Name = "InheritedFunctionOne" ; |
43 | I.Bases.back().Members.emplace_back(Args: TypeInfo("int" ), Args: "N" , |
44 | Args: AccessSpecifier::AS_public); |
45 | |
46 | // F is in the global namespace |
47 | I.Parents.emplace_back(Args: EmptySID, Args: "F" , Args: InfoType::IT_record, Args: "" ); |
48 | I.VirtualParents.emplace_back(Args: EmptySID, Args: "G" , Args: InfoType::IT_record, |
49 | Args: "path::to::G::G" , Args: "path/to/G" ); |
50 | |
51 | I.Children.Records.emplace_back(args: EmptySID, args: "ChildStruct" , args: InfoType::IT_record, |
52 | args: "path::to::A::r::ChildStruct" , args: "path/to/A/r" ); |
53 | I.Children.Functions.emplace_back(); |
54 | I.Children.Functions.back().Name = "OneFunction" ; |
55 | |
56 | auto G = getJSONGenerator(); |
57 | assert(G); |
58 | std::string Buffer; |
59 | llvm::raw_string_ostream Actual(Buffer); |
60 | auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext()); |
61 | assert(!Err); |
62 | std::string Expected = R"raw({ |
63 | "Bases": [ |
64 | { |
65 | "Access": "public", |
66 | "FullName": "", |
67 | "IsParent": true, |
68 | "IsTypedef": false, |
69 | "IsVirtual": true, |
70 | "Name": "F", |
71 | "Path": "path/to/F", |
72 | "PublicFunctions": [ |
73 | { |
74 | "IsStatic": false, |
75 | "Name": "InheritedFunctionOne", |
76 | "ReturnType": { |
77 | "IsBuiltIn": false, |
78 | "IsTemplate": false, |
79 | "Name": "", |
80 | "QualName": "", |
81 | "USR": "0000000000000000000000000000000000000000" |
82 | }, |
83 | "USR": "0000000000000000000000000000000000000000" |
84 | } |
85 | ], |
86 | "PublicMembers": [ |
87 | { |
88 | "Name": "N", |
89 | "Type": "int" |
90 | } |
91 | ], |
92 | "TagType": "struct", |
93 | "USR": "0000000000000000000000000000000000000000" |
94 | } |
95 | ], |
96 | "Enums": [ |
97 | { |
98 | "Members": [ |
99 | { |
100 | "Name": "RED", |
101 | "Value": "0" |
102 | } |
103 | ], |
104 | "Name": "Color", |
105 | "Scoped": false, |
106 | "USR": "0000000000000000000000000000000000000000" |
107 | } |
108 | ], |
109 | "FullName": "", |
110 | "IsTypedef": false, |
111 | "Location": { |
112 | "Filename": "main.cpp", |
113 | "LineNumber": 1 |
114 | }, |
115 | "Name": "Foo", |
116 | "Namespace": [ |
117 | "GlobalNamespace" |
118 | ], |
119 | "Parents": [ |
120 | { |
121 | "Name": "F", |
122 | "Path": "", |
123 | "QualName": "", |
124 | "USR": "0000000000000000000000000000000000000000" |
125 | } |
126 | ], |
127 | "Path": "GlobalNamespace", |
128 | "ProtectedMembers": [ |
129 | { |
130 | "Name": "X", |
131 | "Type": "int" |
132 | } |
133 | ], |
134 | "PublicFunctions": [ |
135 | { |
136 | "IsStatic": false, |
137 | "Name": "OneFunction", |
138 | "ReturnType": { |
139 | "IsBuiltIn": false, |
140 | "IsTemplate": false, |
141 | "Name": "", |
142 | "QualName": "", |
143 | "USR": "0000000000000000000000000000000000000000" |
144 | }, |
145 | "USR": "0000000000000000000000000000000000000000" |
146 | } |
147 | ], |
148 | "Records": [ |
149 | { |
150 | "Name": "ChildStruct", |
151 | "Path": "path/to/A/r", |
152 | "QualName": "path::to::A::r::ChildStruct", |
153 | "USR": "0000000000000000000000000000000000000000" |
154 | } |
155 | ], |
156 | "TagType": "class", |
157 | "Template": { |
158 | "Parameters": [ |
159 | "class T" |
160 | ] |
161 | }, |
162 | "USR": "0000000000000000000000000000000000000000", |
163 | "VirtualParents": [ |
164 | { |
165 | "Name": "G", |
166 | "Path": "path/to/G", |
167 | "QualName": "path::to::G::G", |
168 | "USR": "0000000000000000000000000000000000000000" |
169 | } |
170 | ] |
171 | })raw" ; |
172 | EXPECT_EQ(Expected, Actual.str()); |
173 | } |
174 | |
175 | TEST(JSONGeneratorTest, emitNamespaceJSON) { |
176 | NamespaceInfo I; |
177 | I.Name = "Namespace" ; |
178 | I.Path = "path/to/A" ; |
179 | I.Namespace.emplace_back(Args: EmptySID, Args: "A" , Args: InfoType::IT_namespace); |
180 | |
181 | I.Children.Namespaces.emplace_back( |
182 | args: EmptySID, args: "ChildNamespace" , args: InfoType::IT_namespace, |
183 | args: "path::to::A::Namespace::ChildNamespace" , args: "path/to/A/Namespace" ); |
184 | I.Children.Records.emplace_back(args: EmptySID, args: "ChildStruct" , args: InfoType::IT_record, |
185 | args: "path::to::A::Namespace::ChildStruct" , |
186 | args: "path/to/A/Namespace" ); |
187 | I.Children.Functions.emplace_back(); |
188 | I.Children.Functions.back().Name = "OneFunction" ; |
189 | I.Children.Functions.back().Access = AccessSpecifier::AS_none; |
190 | I.Children.Enums.emplace_back(); |
191 | I.Children.Enums.back().Name = "OneEnum" ; |
192 | |
193 | auto G = getJSONGenerator(); |
194 | assert(G); |
195 | std::string Buffer; |
196 | llvm::raw_string_ostream Actual(Buffer); |
197 | auto Err = G->generateDocForInfo(I: &I, OS&: Actual, CDCtx: ClangDocContext()); |
198 | assert(!Err); |
199 | std::string Expected = R"raw({ |
200 | "Enums": [ |
201 | { |
202 | "Name": "OneEnum", |
203 | "Scoped": false, |
204 | "USR": "0000000000000000000000000000000000000000" |
205 | } |
206 | ], |
207 | "Functions": [ |
208 | { |
209 | "IsStatic": false, |
210 | "Name": "OneFunction", |
211 | "ReturnType": { |
212 | "IsBuiltIn": false, |
213 | "IsTemplate": false, |
214 | "Name": "", |
215 | "QualName": "", |
216 | "USR": "0000000000000000000000000000000000000000" |
217 | }, |
218 | "USR": "0000000000000000000000000000000000000000" |
219 | } |
220 | ], |
221 | "Name": "Namespace", |
222 | "Namespace": [ |
223 | "A" |
224 | ], |
225 | "Namespaces": [ |
226 | { |
227 | "Name": "ChildNamespace", |
228 | "Path": "path/to/A/Namespace", |
229 | "QualName": "path::to::A::Namespace::ChildNamespace", |
230 | "USR": "0000000000000000000000000000000000000000" |
231 | } |
232 | ], |
233 | "Path": "path/to/A", |
234 | "Records": [ |
235 | { |
236 | "Name": "ChildStruct", |
237 | "Path": "path/to/A/Namespace", |
238 | "QualName": "path::to::A::Namespace::ChildStruct", |
239 | "USR": "0000000000000000000000000000000000000000" |
240 | } |
241 | ], |
242 | "USR": "0000000000000000000000000000000000000000" |
243 | })raw" ; |
244 | EXPECT_EQ(Expected, Actual.str()); |
245 | } |
246 | } // namespace doc |
247 | } // namespace clang |
248 | |