Skip to content

Commit 8451cef

Browse files
committed
Change XML comments to be tested at run-time
Signed-off-by: Dimitar Dobrev <[email protected]>
1 parent 8683546 commit 8451cef

File tree

5 files changed

+207
-139
lines changed

5 files changed

+207
-139
lines changed

src/Generator.Tests/AST/TestAST.cs

Lines changed: 1 addition & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -402,75 +402,6 @@ public void TestFunctionInstantiatedFrom()
402402
classTemplate.TemplatedClass.Constructors.First(c => !c.IsCopyConstructor && !c.IsMoveConstructor));
403403
}
404404

405-
[Test]
406-
public void TestComments()
407-
{
408-
var @class = AstContext.FindCompleteClass("TestComments");
409-
var textGenerator = new TextGenerator();
410-
textGenerator.Print(@class.Comment.FullComment, CommentKind.BCPLSlash);
411-
Assert.AreEqual(@"/// <summary>
412-
/// <para>Hash set/map base class.</para>
413-
/// <para>Note that to prevent extra memory use due to vtable pointer, %HashBase intentionally does not declare a virtual destructor</para>
414-
/// <para>and therefore %HashBase pointers should never be used.</para>
415-
/// </summary>
416-
".Replace("\r", string.Empty), textGenerator.StringBuilder.Replace("\r", string.Empty).ToString());
417-
418-
var method = @class.Methods.First(m => m.Name == "GetIOHandlerControlSequence");
419-
textGenerator.StringBuilder.Clear();
420-
textGenerator.Print(method.Comment.FullComment, CommentKind.BCPL);
421-
Assert.AreEqual(@"// <summary>
422-
// <para>Get the string that needs to be written to the debugger stdin file</para>
423-
// <para>handle when a control character is typed.</para>
424-
// </summary>
425-
// <param name=""ch"">The character that was typed along with the control key</param>
426-
// <returns>
427-
// <para>The string that should be written into the file handle that is</para>
428-
// <para>feeding the input stream for the debugger, or NULL if there is</para>
429-
// <para>no string for this control key.</para>
430-
// </returns>
431-
// <remarks>
432-
// <para>Some GUI programs will intercept &quot;control + char&quot; sequences and want</para>
433-
// <para>to have them do what normally would happen when using a real</para>
434-
// <para>terminal, so this function allows GUI programs to emulate this</para>
435-
// <para>functionality.</para>
436-
// </remarks>
437-
".Replace("\r", string.Empty), textGenerator.StringBuilder.Replace("\r", string.Empty).ToString());
438-
439-
var methodTestDoxygen = @class.Methods.First(m => m.Name == "SBAttachInfo");
440-
textGenerator.StringBuilder.Clear();
441-
textGenerator.Print(methodTestDoxygen.Comment.FullComment, CommentKind.BCPLSlash);
442-
Assert.AreEqual(@"/// <summary>Attach to a process by name.</summary>
443-
/// <param name=""path"">A full or partial name for the process to attach to.</param>
444-
/// <param name=""wait_for"">
445-
/// <para>If <c>false,</c> attach to an existing process whose name matches.</para>
446-
/// <para>If <c>true,</c> then wait for the next process whose name matches.</para>
447-
/// </param>
448-
/// <remarks>
449-
/// <para>This function implies that a future call to SBTarget::Attach(...)</para>
450-
/// <para>will be synchronous.</para>
451-
/// </remarks>
452-
".Replace("\r", string.Empty), textGenerator.StringBuilder.Replace("\r", string.Empty).ToString());
453-
454-
var methodDoxygenCustomTags = @class.Methods.First(m => m.Name == "glfwDestroyWindow");
455-
new CleanCommentsPass().VisitFull(methodDoxygenCustomTags.Comment.FullComment);
456-
textGenerator.StringBuilder.Clear();
457-
textGenerator.Print(methodDoxygenCustomTags.Comment.FullComment, CommentKind.BCPLSlash);
458-
Assert.AreEqual(@"/// <summary>Destroys the specified window and its context.</summary>
459-
/// <param name=""window"">The window to destroy.</param>
460-
/// <remarks>
461-
/// <para>This function destroys the specified window and its context. On calling</para>
462-
/// <para>this function, no further callbacks will be called for that window.</para>
463-
/// <para>If the context of the specified window is current on the main thread, it is</para>
464-
/// <para>detached before being destroyed.</para>
465-
/// <para>The context of the specified window must not be current on any other</para>
466-
/// <para>thread when this function is called.</para>
467-
/// <para>This function must not be called from a callback.</para>
468-
/// <para>This function must only be called from the main thread.</para>
469-
/// <para>Added in version 3.0. Replaces `glfwCloseWindow`.</para>
470-
/// </remarks>
471-
".Replace("\r", string.Empty), textGenerator.StringBuilder.Replace("\r", string.Empty).ToString());
472-
}
473-
474405
[Test]
475406
public void TestCompletionOfClassTemplates()
476407
{
@@ -515,7 +446,7 @@ public void TestPrintingSpecializationWithConstValue()
515446
[Test]
516447
public void TestLayoutBase()
517448
{
518-
var @class = AstContext.FindCompleteClass("TestComments");
449+
var @class = AstContext.FindCompleteClass("HasConstFunction");
519450
Assert.That(@class.Layout.Bases.Count, Is.EqualTo(0));
520451
}
521452

tests/NamespacesDerived/NamespacesDerived.CSharp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<EnableGeneratorCompileItems>false</EnableGeneratorCompileItems>
4+
<DocumentationFile>NamespacesDerived.CSharp.xml</DocumentationFile>
45
</PropertyGroup>
56

67
<ItemGroup>

tests/NamespacesDerived/NamespacesDerived.Tests.cs

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
using NamespacesDerived;
1+
using System.IO;
2+
using System.Xml.Linq;
3+
using System.Linq;
4+
using System;
5+
using System.Reflection;
26
using NUnit.Framework;
7+
using NamespacesDerived;
38

49
[TestFixture]
510
public class NamespaceDerivedTests
@@ -39,6 +44,137 @@ public void TestOverrideMethodFromDependency()
3944
}
4045
}
4146

47+
[Test]
48+
public void TestComments()
49+
{
50+
Type testCommentsType = typeof(TestComments);
51+
Assembly assembly = testCommentsType.Assembly;
52+
string dir = Path.GetDirectoryName(assembly.Location);
53+
string xml = Path.ChangeExtension(Path.GetFileName(assembly.Location), ".xml");
54+
XDocument xmlDoc = XDocument.Load(Path.Combine(dir, xml));
55+
XElement members = xmlDoc.Root.Element("members");
56+
57+
TestClassComment(testCommentsType, members);
58+
TestGetIOHandlerControlSequence(testCommentsType, members);
59+
TestSBAttachInfo(testCommentsType, members);
60+
TestGlfwDestroyWindow(testCommentsType, members);
61+
}
62+
63+
private static void TestClassComment(Type testCommentsType, XElement members)
64+
{
65+
string testCommentsName = $"T:{testCommentsType.FullName}";
66+
XElement testComments = members.Elements().Single(
67+
m => m.Attribute("name").Value == testCommentsName);
68+
Assert.That(testComments.Element("summary").Elements().Select(p => p.Value), Is.EquivalentTo(
69+
new[]
70+
{
71+
"Hash set/map base class.",
72+
"Note that to prevent extra memory use due to vtable pointer, %HashBase intentionally does not declare a virtual destructor",
73+
"and therefore %HashBase pointers should never be used."
74+
}));
75+
}
76+
77+
private static void TestGetIOHandlerControlSequence(Type testCommentsType, XElement members)
78+
{
79+
const string name = "GetIOHandlerControlSequence";
80+
XElement method = FindMethod(testCommentsType, members, name);
81+
Assert.That(method.Element("summary").Elements("para").Select(p => p.Value),
82+
Is.EquivalentTo(
83+
new[]
84+
{
85+
"Get the string that needs to be written to the debugger stdin file",
86+
"handle when a control character is typed."
87+
}));
88+
Assert.That(method.Element("returns").Elements("para").Select(p => p.Value),
89+
Is.EquivalentTo(
90+
new[]
91+
{
92+
"The string that should be written into the file handle that is",
93+
"feeding the input stream for the debugger, or NULL if there is",
94+
"no string for this control key."
95+
}));
96+
Assert.That(method.Element("remarks").Elements("para").Select(p => p.Value),
97+
Is.EquivalentTo(
98+
new[]
99+
{
100+
"Some GUI programs will intercept \"control + char\" sequences and want",
101+
"to have them do what normally would happen when using a real",
102+
"terminal, so this function allows GUI programs to emulate this",
103+
"functionality."
104+
}));
105+
XElement ch = method.Element("param");
106+
Assert.That(ch.Attribute("name").Value,
107+
Is.EqualTo(testCommentsType.GetMethod(name).GetParameters()[0].Name));
108+
Assert.That(ch.Value, Is.EqualTo("The character that was typed along with the control key"));
109+
}
110+
111+
private static void TestSBAttachInfo(Type testCommentsType, XElement members)
112+
{
113+
const string name = "SBAttachInfo";
114+
XElement method = FindMethod(testCommentsType, members, name);
115+
Assert.That(method.Element("remarks").Elements("para").Select(p => p.Value),
116+
Is.EquivalentTo(
117+
new[]
118+
{
119+
"This function implies that a future call to SBTarget::Attach(...)",
120+
"will be synchronous."
121+
}));
122+
123+
ParameterInfo[] @params = testCommentsType.GetMethod(name).GetParameters();
124+
125+
XElement path = method.Element("param");
126+
Assert.That(path.Attribute("name").Value,
127+
Is.EqualTo(@params[0].Name));
128+
Assert.That(path.Value, Is.EqualTo("A full or partial name for the process to attach to."));
129+
130+
XElement wait_for = (XElement) path.NextNode;
131+
Assert.That(wait_for.Attribute("name").Value, Is.EqualTo(@params[1].Name));
132+
Assert.That(wait_for.Elements("para").Select(p => string.Concat(p.Nodes())),
133+
Is.EquivalentTo(
134+
new[]
135+
{
136+
"If <c>false,</c> attach to an existing process whose name matches.",
137+
"If <c>true,</c> then wait for the next process whose name matches."
138+
}));
139+
}
140+
141+
private static void TestGlfwDestroyWindow(Type testCommentsType, XElement members)
142+
{
143+
const string name = "GlfwDestroyWindow";
144+
XElement method = FindMethod(testCommentsType, members, name);
145+
Assert.That(method.Element("summary").Value,
146+
Is.EqualTo("Destroys the specified window and its context."));
147+
Assert.That(method.Element("remarks").Elements("para").Select(p => p.Value),
148+
Is.EquivalentTo(
149+
new[]
150+
{
151+
"This function destroys the specified window and its context. On calling",
152+
"this function, no further callbacks will be called for that window.",
153+
"If the context of the specified window is current on the main thread, it is",
154+
"detached before being destroyed.",
155+
"The context of the specified window must not be current on any other",
156+
"thread when this function is called.",
157+
"This function must not be called from a callback.",
158+
"_safety This function must only be called from the main thread.",
159+
"Added in version 3.0. Replaces `glfwCloseWindow`."
160+
}));
161+
XElement window = method.Element("param");
162+
Assert.That(window.Attribute("name").Value,
163+
Is.EqualTo(testCommentsType.GetMethod(name).GetParameters()[0].Name));
164+
Assert.That(window.Value, Is.EqualTo("The window to destroy."));
165+
}
166+
167+
private static XElement FindMethod(Type testCommentsType, XElement members, string name)
168+
{
169+
string fullName = $"M:{testCommentsType.FullName}.{name}";
170+
return members.Elements().Single(
171+
m =>
172+
{
173+
string name = m.Attribute("name").Value;
174+
return name.Substring(0, Math.Max(name.IndexOf('('), 0)) == fullName;
175+
});
176+
}
177+
42178
private class OverrideMethodFromDependency : HasVirtualInDependency
43179
{
44180
public override int VirtualInCore(int parameter) => 2;

tests/NamespacesDerived/NamespacesDerived.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,71 @@ namespace NamespacesBase
100100
Base base;
101101
};
102102
}
103+
104+
/// Hash set/map base class.
105+
/** Note that to prevent extra memory use due to vtable pointer, %HashBase intentionally does not declare a virtual destructor
106+
and therefore %HashBase pointers should never be used.
107+
*/
108+
class TestComments
109+
{
110+
public:
111+
//----------------------------------------------------------------------
112+
/// Get the string that needs to be written to the debugger stdin file
113+
/// handle when a control character is typed.
114+
///
115+
/// Some GUI programs will intercept "control + char" sequences and want
116+
/// to have them do what normally would happen when using a real
117+
/// terminal, so this function allows GUI programs to emulate this
118+
/// functionality.
119+
///
120+
/// @param[in] ch
121+
/// The character that was typed along with the control key
122+
///
123+
/// @return
124+
/// The string that should be written into the file handle that is
125+
/// feeding the input stream for the debugger, or NULL if there is
126+
/// no string for this control key.
127+
//----------------------------------------------------------------------
128+
const char* GetIOHandlerControlSequence(char ch);
129+
130+
//------------------------------------------------------------------
131+
/// Attach to a process by name.
132+
///
133+
/// This function implies that a future call to SBTarget::Attach(...)
134+
/// will be synchronous.
135+
///
136+
/// @param[in] path
137+
/// A full or partial name for the process to attach to.
138+
///
139+
/// @param[in] wait_for
140+
/// If \b false, attach to an existing process whose name matches.
141+
/// If \b true, then wait for the next process whose name matches.
142+
//------------------------------------------------------------------
143+
int SBAttachInfo(const char* path, bool wait_for);
144+
145+
/*! @brief Destroys the specified window and its context.
146+
*
147+
* This function destroys the specified window and its context. On calling
148+
* this function, no further callbacks will be called for that window.
149+
*
150+
* If the context of the specified window is current on the main thread, it is
151+
* detached before being destroyed.
152+
*
153+
* @param[in] window The window to destroy.
154+
*
155+
* @note The context of the specified window must not be current on any other
156+
* thread when this function is called.
157+
*
158+
* @reentrancy This function must not be called from a callback.
159+
*
160+
* @thread_safety This function must only be called from the main thread.
161+
*
162+
* @since Added in version 3.0. Replaces `glfwCloseWindow`.
163+
*/
164+
void glfwDestroyWindow(int* window);
165+
166+
/**
167+
168+
*/
169+
class LinphoneAddress {};
170+
};

tests/Native/AST.h

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -128,74 +128,6 @@ void instantiatesTemplate(TestSpecializationArguments<int> i, TestSpecialization
128128
{
129129
}
130130

131-
/// Hash set/map base class.
132-
/** Note that to prevent extra memory use due to vtable pointer, %HashBase intentionally does not declare a virtual destructor
133-
and therefore %HashBase pointers should never be used.
134-
*/
135-
class TestComments
136-
{
137-
public:
138-
//----------------------------------------------------------------------
139-
/// Get the string that needs to be written to the debugger stdin file
140-
/// handle when a control character is typed.
141-
///
142-
/// Some GUI programs will intercept "control + char" sequences and want
143-
/// to have them do what normally would happen when using a real
144-
/// terminal, so this function allows GUI programs to emulate this
145-
/// functionality.
146-
///
147-
/// @param[in] ch
148-
/// The character that was typed along with the control key
149-
///
150-
/// @return
151-
/// The string that should be written into the file handle that is
152-
/// feeding the input stream for the debugger, or NULL if there is
153-
/// no string for this control key.
154-
//----------------------------------------------------------------------
155-
const char * GetIOHandlerControlSequence(char ch);
156-
157-
//------------------------------------------------------------------
158-
/// Attach to a process by name.
159-
///
160-
/// This function implies that a future call to SBTarget::Attach(...)
161-
/// will be synchronous.
162-
///
163-
/// @param[in] path
164-
/// A full or partial name for the process to attach to.
165-
///
166-
/// @param[in] wait_for
167-
/// If \b false, attach to an existing process whose name matches.
168-
/// If \b true, then wait for the next process whose name matches.
169-
//------------------------------------------------------------------
170-
int SBAttachInfo(const char *path, bool wait_for);
171-
172-
/*! @brief Destroys the specified window and its context.
173-
*
174-
* This function destroys the specified window and its context. On calling
175-
* this function, no further callbacks will be called for that window.
176-
*
177-
* If the context of the specified window is current on the main thread, it is
178-
* detached before being destroyed.
179-
*
180-
* @param[in] window The window to destroy.
181-
*
182-
* @note The context of the specified window must not be current on any other
183-
* thread when this function is called.
184-
*
185-
* @reentrancy This function must not be called from a callback.
186-
*
187-
* @thread_safety This function must only be called from the main thread.
188-
*
189-
* @since Added in version 3.0. Replaces `glfwCloseWindow`.
190-
*/
191-
void glfwDestroyWindow(int* window);
192-
193-
/**
194-
195-
*/
196-
class LinphoneAddress {};
197-
};
198-
199131
template <typename T>
200132
class ForwardedTemplate;
201133

0 commit comments

Comments
 (0)