1 /**
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that the following conditions are
4 * met :
5 *
6 * . Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 *
9 * . Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * . The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $Id: $
29 */
30
31 package cppncss.counter;
32
33 import java.io.StringReader;
34 import junit.framework.TestCase;
35 import cppast.AstTranslationUnit;
36 import cppast.Node;
37 import cppast.ParseException;
38 import cppast.Parser;
39
40 /**
41 * @author Mathieu Champlon
42 */
43 public class FunctionNameExtractorTest extends TestCase
44 {
45 private String extract( final String data ) throws ParseException
46 {
47 final Node node = new Parser( new StringReader( data ) ).translation_unit();
48 return (String)node.jjtAccept( new FunctionNameExtractor(), null );
49 }
50
51 public void testNotFunctionReturnsNull() throws ParseException
52 {
53 assertNull( extract( "" ) );
54 }
55
56 public void testFunctionDefinitionWithoutParameters() throws ParseException
57 {
58 assertEquals( "MyFunction()", extract( "void MyFunction() {}" ) );
59 }
60
61 public void testFunctionDefinitionWithIntegerParameter() throws ParseException
62 {
63 assertEquals( "MyFunction( int )", extract( "void MyFunction( int p ) {}" ) );
64 }
65
66 public void testFunctionDefinitionWithIntegerParameterWithoutParameterName() throws ParseException
67 {
68 assertEquals( "MyFunction( int )", extract( "void MyFunction( int ) {}" ) );
69 }
70
71 public void testFunctionDefinitionWithIntegerPointerParameter() throws ParseException
72 {
73 assertEquals( "MyFunction( int* )", extract( "void MyFunction( int* p ) {}" ) );
74 }
75
76 public void testFunctionDefinitionWithIntegerPointerParameterWithoutParameterName() throws ParseException
77 {
78 assertEquals( "MyFunction( int* )", extract( "void MyFunction( int* ) {}" ) );
79 }
80
81 public void testFunctionDefinitionWithIntegerReferencePointerConstParameter() throws ParseException
82 {
83 assertEquals( "MyFunction( int*& )", extract( "void MyFunction( int*& p ) {}" ) );
84 }
85
86 public void testFunctionDefinitionWithIntegerReferencePointerConstParameterWithoutParameterName()
87 throws ParseException
88 {
89 assertEquals( "MyFunction( int*& )", extract( "void MyFunction( int*& ) {}" ) );
90 }
91
92 public void testFunctionDefinitionWithConstPointerConstParameter() throws ParseException
93 {
94 assertEquals( "MyFunction( const int* const )", extract( "void MyFunction( const int* const p ) {}" ) );
95 }
96
97 public void testFunctionDefinitionWithConstPointerConstParameterWithoutParameterName() throws ParseException
98 {
99 assertEquals( "MyFunction( const int* const )", extract( "void MyFunction( const int* const ) {}" ) );
100 }
101
102 public void testFunctionDefinitionWithUnsignedIntegerParameter() throws ParseException
103 {
104 assertEquals( "MyFunction( unsigned int )", extract( "void MyFunction( unsigned int p ) {}" ) );
105 }
106
107 public void testFunctionDefinitionWithUnsignedIntegerParameterWithoutParameterName() throws ParseException
108 {
109 assertEquals( "MyFunction( unsigned int )", extract( "void MyFunction( unsigned int ) {}" ) );
110 }
111
112 public void testFunctionDefinitionWithUnsignedIntegerPointerParameter() throws ParseException
113 {
114 assertEquals( "MyFunction( unsigned int* )", extract( "void MyFunction( unsigned int* p ) {}" ) );
115 }
116
117 public void testFunctionDefinitionWithUnsignedIntegerPointerParameterWithoutParameterName() throws ParseException
118 {
119 assertEquals( "MyFunction( unsigned int* )", extract( "void MyFunction( unsigned int* ) {}" ) );
120 }
121
122 public void testFunctionDefinitionWithSeveralParameters() throws ParseException
123 {
124 assertEquals( "MyFunction( int, float&, const char* )",
125 extract( "void MyFunction( int p1, float& p2, const char* p3 ) {}" ) );
126 }
127
128 public void testFunctionDefinitionWithSeveralParametersWithoutParameterNames() throws ParseException
129 {
130 assertEquals( "MyFunction( int, float&, const char* )",
131 extract( "void MyFunction( int, float&, const char* ) {}" ) );
132 }
133
134 public void testConstMethodDefinition() throws ParseException
135 {
136 assertEquals( "MyClass::MyMethod()", extract( "void MyClass::MyMethod() const {}" ) );
137 }
138
139 public void testMethodDefinitionWithConstReferenceReturnType() throws ParseException
140 {
141 assertEquals( "MyClass::MyMethod()", extract( "const MyType& MyClass::MyMethod() {}" ) );
142 }
143
144 public void testEqualityOperatorDefinition() throws ParseException
145 {
146 assertEquals( "MyClass::operator ==( const MyClass& )",
147 extract( "bool MyClass::operator==( const MyClass& rhs ) const {}" ) );
148 }
149
150 public void testConversionOperatorDefinition() throws ParseException
151 {
152 assertEquals( "MyClass::operator const unsigned char*()",
153 extract( "MyClass::operator const unsigned char*() const {}" ) );
154 }
155
156 public void testConstructorDefinition() throws ParseException
157 {
158 assertEquals( "MyClass::MyClass()", extract( "MyClass::MyClass() {}" ) );
159 }
160
161 public void testConstructorDefinitionWithParameter() throws ParseException
162 {
163 assertEquals( "MyClass::MyClass( int )", extract( "MyClass::MyClass( int p ) {}" ) );
164 }
165
166 public void testDestructorDefinition() throws ParseException
167 {
168 assertEquals( "MyClass::~MyClass()", extract( "MyClass::~MyClass() {}" ) );
169 }
170
171 public void testFunctionBodyDoesNotAlterFunctionSignature() throws ParseException
172 {
173 assertEquals( "MyFunction()", extract( "void MyFunction() { char *p; }" ) );
174 }
175
176 public void testArrayArgument() throws ParseException
177 {
178 assertEquals( "MyFunction( MyType[3] )", extract( "void MyFunction( MyType p[3] ) {}" ) );
179 }
180
181 public void testArrayArgumentWithoutParameterName() throws ParseException
182 {
183 assertEquals( "MyFunction( MyType[3] )", extract( "void MyFunction( MyType[3] ) {}" ) );
184 }
185
186 public void testTemplateClassMethod() throws ParseException
187 {
188 assertEquals( "MyClass< T, F >::MyMethod()", extract( "void MyClass< T, F >::MyMethod() {}" ) );
189 }
190
191 public void testTemplateParameterFunction() throws ParseException
192 {
193 assertEquals( "MyFunction( MyClass< T, F >& )", extract( "void MyFunction( MyClass< T, F >& p ) {}" ) );
194 }
195
196 public void testTemplateParameterFunctionWithoutParameterName() throws ParseException
197 {
198 assertEquals( "MyFunction( MyClass< T, F >& )", extract( "void MyFunction( MyClass< T, F >& ) {}" ) );
199 }
200
201 public void testPointerOnMemberParameterFunction() throws ParseException
202 {
203 assertEquals( "MyFunction( void (C::*)( char, float ) )",
204 extract( "void MyFunction( void (C::*M)( char, float ) ) {}" ) );
205 }
206
207 public void testPointerOnFunctionParameterFunction() throws ParseException
208 {
209 assertEquals( "MyFunction( void (*)( char, float ) )",
210 extract( "void MyFunction( void (*F)( char, float ) ) {}" ) );
211 }
212
213 public void testFunctionReturningPointerOnFunction() throws ParseException
214 {
215 assertEquals( "MyFunction( int )", extract( "void (*MyFunction( int ))( char, float ) {}" ) );
216 }
217
218 public void testParenthesisOperatorDefinition() throws ParseException
219 {
220 assertEquals( "MyClass::operator()( int )", extract( "void MyClass::operator()( int i ) {}" ) );
221 }
222
223 public void testFunctionInAnonymousNamespace() throws ParseException
224 {
225 assertEquals( "`anonymous-namespace'::MyFunction()", extract( "namespace { void MyFunction(); }" ) );
226 }
227
228 public void testMethodOfClassDefinedInFunction() throws ParseException
229 {
230 final String content = "void MyFunction() { class MyClass{ void MyMethod(); }; }";
231 final AstTranslationUnit root = new Parser( new StringReader( content ) ).translation_unit();
232 final Node node = root.jjtGetChild( 0 ).jjtGetChild( 2 ).jjtGetChild( 0 );
233 final String actual = (String)node.jjtAccept( new FunctionNameExtractor(), null );
234
235 assertEquals( "MyFunction::MyClass::MyMethod()", actual );
236 }
237
238 public void testMethodOfClassDefinedLocally() throws ParseException
239 {
240 final String content = "void MyFunction() { { class MyClass{ void MyMethod(); }; } }";
241 final AstTranslationUnit root = new Parser( new StringReader( content ) ).translation_unit();
242 final Node node = root.jjtGetChild( 0 ).jjtGetChild( 2 ).jjtGetChild( 0 );
243 final String actual = (String)node.jjtAccept( new FunctionNameExtractor(), null );
244
245 assertEquals( "MyFunction::MyClass::MyMethod()", actual );
246 }
247 }