Package com.google.test.metric.cpp

Source Code of com.google.test.metric.cpp.CppParserTest

/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.test.metric.cpp;

import com.google.test.metric.ParameterInfo;
import com.google.test.metric.Visibility;
import com.google.test.metric.cpp.dom.AssignmentExpression;
import com.google.test.metric.cpp.dom.BaseClass;
import com.google.test.metric.cpp.dom.BaseClass.AccessSpecifier;
import com.google.test.metric.cpp.dom.BreakStatement;
import com.google.test.metric.cpp.dom.CaseStatement;
import com.google.test.metric.cpp.dom.ClassDeclaration;
import com.google.test.metric.cpp.dom.DefaultStatement;
import com.google.test.metric.cpp.dom.ElseStatement;
import com.google.test.metric.cpp.dom.Expression;
import com.google.test.metric.cpp.dom.ExpressionStatement;
import com.google.test.metric.cpp.dom.FunctionDeclaration;
import com.google.test.metric.cpp.dom.FunctionDefinition;
import com.google.test.metric.cpp.dom.FunctionInvocation;
import com.google.test.metric.cpp.dom.IfStatement;
import com.google.test.metric.cpp.dom.LoopStatement;
import com.google.test.metric.cpp.dom.Name;
import com.google.test.metric.cpp.dom.Namespace;
import com.google.test.metric.cpp.dom.NodeList;
import com.google.test.metric.cpp.dom.ReturnStatement;
import com.google.test.metric.cpp.dom.SwitchStatement;
import com.google.test.metric.cpp.dom.TernaryOperation;
import com.google.test.metric.cpp.dom.TranslationUnit;
import com.google.test.metric.cpp.dom.VariableDeclaration;

import junit.framework.TestCase;

import java.util.List;

public class CppParserTest extends TestCase {

  private TranslationUnit parse(String source, NodeDictionary dict)
      throws Exception {
    return new Parser().parse(source, dict);
  }

  private TranslationUnit parse(String source) throws Exception {
    return new Parser().parse(source);
  }

  public void testEmptyClass() throws Exception {
    TranslationUnit unit = parse("class A{};");
    ClassDeclaration classA = unit.getChild(0);
    assertEquals("A", classA.getName());
  }

  public void testTwoClasses() throws Exception {
    TranslationUnit unit = parse("class A{}; class B{};");
    ClassDeclaration classA = unit.getChild(0);
    assertEquals("A", classA.getName());
    ClassDeclaration classB = unit.getChild(1);
    assertEquals("B", classB.getName());
  }

  public void testNestedClass() throws Exception {
    TranslationUnit unit = parse("class A{ class B{}; };");
    ClassDeclaration classA = unit.getChild(0);
    assertEquals("A", classA.getName());
    ClassDeclaration classB = classA.getChild(0);
    assertEquals("B", classB.getName());
  }

  public void testUnnamedNamespace() throws Exception {
    TranslationUnit unit = parse("namespace {}");
    Namespace namespace = unit.getChild(0);
    assertNull(namespace.getName());
  }

  public void testEmptyNamespace() throws Exception {
    TranslationUnit unit = parse("namespace A{}");
    Namespace namespaceA = unit.getChild(0);
    assertEquals("A", namespaceA.getName());
  }

  public void testTwoNamespaces() throws Exception {
    TranslationUnit unit = parse("namespace A{} namespace B{}");
    Namespace namespaceA = unit.getChild(0);
    assertEquals("A", namespaceA.getName());
    Namespace namespaceB = unit.getChild(1);
    assertEquals("B", namespaceB.getName());
  }

  public void testNestedNamespace() throws Exception {
    TranslationUnit unit = parse("namespace A{ namespace B{} }");
    Namespace namespaceA = unit.getChild(0);
    assertEquals("A", namespaceA.getName());
    Namespace namespaceB = namespaceA.getChild(0);
    assertEquals("B", namespaceB.getName());
  }

  public void testClassInNamespace() throws Exception {
    TranslationUnit unit = parse("namespace A{ class B{}; }");
    Namespace namespaceA = unit.getChild(0);
    assertEquals("A", namespaceA.getName());
    ClassDeclaration classB = namespaceA.getChild(0);
    assertEquals("B", classB.getName());
  }

  public void testGlobalFunctionDeclaration() throws Exception {
    TranslationUnit unit = parse("void foo();");
    FunctionDeclaration functionFoo = unit.getChild(0);
    assertEquals("foo", functionFoo.getName());
  }

  public void testGlobalVarableDeclaration() throws Exception {
    TranslationUnit unit = parse("int a = 0, b = 1, c;");
    VariableDeclaration variableA = unit.getChild(0);
    assertEquals("a", variableA.getName());
    VariableDeclaration variableB = unit.getChild(1);
    assertEquals("b", variableB.getName());
    VariableDeclaration variableC = unit.getChild(2);
    assertEquals("c", variableC.getName());
  }

  public void testFunctionDeclarationInNamespace() throws Exception {
    TranslationUnit unit = parse("namespace A { void foo(); };");
    Namespace namespaceA = unit.getChild(0);
    assertEquals("A", namespaceA.getName());
    FunctionDeclaration functionFoo = namespaceA.getChild(0);
    assertEquals("foo", functionFoo.getName());
  }

  public void testMemberFunctionDeclaration() throws Exception {
    TranslationUnit unit = parse("class A { void foo(); };");
    ClassDeclaration classA = unit.getChild(0);
    assertEquals("A", classA.getName());
    FunctionDeclaration functionFoo = classA.getChild(0);
    assertEquals("foo", functionFoo.getName());
  }

  public void testEmptyGlobalFunction() throws Exception {
    TranslationUnit unit = parse("void foo() {}");
    FunctionDefinition functionFoo = unit.getChild(0);
    assertEquals("foo", functionFoo.getName());
  }

  public void testEmptyFunctionInNamespace() throws Exception {
    TranslationUnit unit = parse("namespace A { void foo() {} }");
    Namespace namespaceA = unit.getChild(0);
    assertEquals("A", namespaceA.getName());
    FunctionDefinition functionFoo = namespaceA.getChild(0);
    assertEquals("foo", functionFoo.getName());
  }

  public void testEmptyMemberFunction() throws Exception {
    TranslationUnit unit = parse("class A { void foo() {} };");
    ClassDeclaration classA = unit.getChild(0);
    assertEquals("A", classA.getName());
    FunctionDefinition functionFoo = classA.getChild(0);
    assertEquals("foo", functionFoo.getName());
    assertEquals(1, functionFoo.getLine());
  }

  public void testFunctionLineNumbers() throws Exception {
    TranslationUnit unit = parse("class A { void foo() {}\n void\n bar() {} };");
    ClassDeclaration classA = unit.getChild(0);
    FunctionDefinition functionFoo = classA.getChild(0);
    assertEquals(1, functionFoo.getLine());
    FunctionDefinition functionBar = classA.getChild(1);
    assertEquals(3, functionBar.getLine());
  }

  public void testSimpleFunction() throws Exception {
    TranslationUnit unit = parse("int foo() { int a = 0; a = a + 1;\n return a; }");
    FunctionDefinition functionFoo = unit.getChild(0);
    assertEquals("foo", functionFoo.getName());
    ReturnStatement returnStatement = functionFoo.getChild(2);
    assertNotNull(returnStatement);
    assertEquals(2, returnStatement.getLineNumber());
  }

  public void testFunctionWithParameters() throws Exception {
    TranslationUnit unit = parse("int foo(int a, int b) { return a + b; }");
    FunctionDefinition functionFoo = unit.getChild(0);
    assertEquals("foo", functionFoo.getName());
    ReturnStatement returnStatement = functionFoo.getChild(0);
    assertNotNull(returnStatement);
    List<ParameterInfo> parameters = functionFoo.getParameters();
    assertEquals(2, parameters.size());
    ParameterInfo parameterA = parameters.get(0);
    assertEquals("a", parameterA.getName());
    assertEquals("int", parameterA.getType().toString());
    ParameterInfo parameterB = parameters.get(1);
    assertEquals("b", parameterB.getName());
    assertEquals("int", parameterB.getType().toString());
  }

  public void testForStatement() throws Exception {
    TranslationUnit unit = parse("void foo() { for(;;); }");
    FunctionDefinition functionFoo = unit.getChild(0);
    LoopStatement forStatement = functionFoo.getChild(0);
    assertNotNull(forStatement);
  }

  public void testWhileStatement() throws Exception {
    TranslationUnit unit = parse("void foo() { while(true); }");
    FunctionDefinition functionFoo = unit.getChild(0);
    LoopStatement whileStatement = functionFoo.getChild(0);
    assertNotNull(whileStatement);
  }

  public void testDoStatement() throws Exception {
    TranslationUnit unit = parse("void foo() { do {} while(true); }");
    FunctionDefinition functionFoo = unit.getChild(0);
    LoopStatement doStatement = functionFoo.getChild(0);
    assertNotNull(doStatement);
  }

  public void testWhileInForStatement() throws Exception {
    TranslationUnit unit = parse("void foo() { for(;;) while(true); }");
    FunctionDefinition functionFoo = unit.getChild(0);
    LoopStatement forStatement = functionFoo.getChild(0);
    assertNotNull(forStatement);
    LoopStatement whileStatement = forStatement.getChild(0);
    assertNotNull(whileStatement);
  }

  public void testForInDoStatement() throws Exception {
    TranslationUnit unit = parse("void foo() { do for(;;); while(true); }");
    FunctionDefinition functionFoo = unit.getChild(0);
    LoopStatement doStatement = functionFoo.getChild(0);
    assertNotNull(doStatement);
    LoopStatement forStatement = doStatement.getChild(0);
    assertNotNull(forStatement);
  }

  public void testForInCompoundDoStatement() throws Exception {
    TranslationUnit unit = parse("void foo() { do { for(;;); } while(true); }");
    FunctionDefinition functionFoo = unit.getChild(0);
    LoopStatement doStatement = functionFoo.getChild(0);
    assertNotNull(doStatement);
    LoopStatement forStatement = doStatement.getChild(0);
    assertNotNull(forStatement);
  }

  public void testForInSeveralCompoundStatements() throws Exception {
    TranslationUnit unit = parse("void foo() { {{{ for(;;); }}} }");
    FunctionDefinition functionFoo = unit.getChild(0);
    LoopStatement forStatement = functionFoo.getChild(0);
    assertNotNull(forStatement);
  }

  public void testIfStatement() throws Exception {
    TranslationUnit unit = parse("void foo() { if (true); }");
    FunctionDefinition functionFoo = unit.getChild(0);
    IfStatement ifStatement = functionFoo.getChild(0);
    assertNotNull(ifStatement);
  }

  public void testIfElseStatement() throws Exception {
    TranslationUnit unit = parse("void foo() { if (true); else; }");
    FunctionDefinition functionFoo = unit.getChild(0);
    IfStatement ifStatement = functionFoo.getChild(0);
    assertNotNull(ifStatement);
    ElseStatement elseStatement = functionFoo.getChild(1);
    assertNotNull(elseStatement);
  }

  public void testCompoundIfElseStatement() throws Exception {
    TranslationUnit unit = parse("void foo() { if (true) {} else {} }");
    FunctionDefinition functionFoo = unit.getChild(0);
    IfStatement ifStatement = functionFoo.getChild(0);
    assertNotNull(ifStatement);
    ElseStatement elseStatement = functionFoo.getChild(1);
    assertNotNull(elseStatement);
  }

  public void testIfElseAndLoopStatements() throws Exception {
    TranslationUnit unit = parse("void foo() { if (true) { for(;;); } else { while(true); } }");
    FunctionDefinition functionFoo = unit.getChild(0);
    IfStatement ifStatement = functionFoo.getChild(0);
    LoopStatement forStatement = ifStatement.getChild(0);
    assertNotNull(forStatement);
    ElseStatement elseStatement = functionFoo.getChild(1);
    LoopStatement whileStatement = elseStatement.getChild(0);
    assertNotNull(whileStatement);
  }

  public void testSwitchStatement() throws Exception {
    TranslationUnit unit = parse("void foo() { switch (a) { case 1: break; } }");
    FunctionDefinition functionFoo = unit.getChild(0);
    SwitchStatement switchStatement = functionFoo.getChild(0);
    CaseStatement caseStatement = switchStatement.getChild(0);
    assertNotNull(caseStatement);
  }

  public void testSwitchStatementWithDefault() throws Exception {
    TranslationUnit unit = parse("void foo() { switch (a) { case 1: break; default: break; } }");
    FunctionDefinition functionFoo = unit.getChild(0);
    SwitchStatement switchStatement = functionFoo.getChild(0);
    CaseStatement caseStatement = switchStatement.getChild(0);
    BreakStatement breakStatement = caseStatement.getChild(0);
    assertNotNull(breakStatement);
    DefaultStatement defaultStatement = switchStatement.getChild(1);
    breakStatement = defaultStatement.getChild(0);
    assertNotNull(breakStatement);
  }

  public void testTernaryOperator() throws Exception {
    TranslationUnit unit = parse("int foo(int a, int b) { return a ? 0 : b; }");
    FunctionDefinition functionFoo = unit.getChild(0);
    ReturnStatement returnStatement = functionFoo.getChild(0);
    TernaryOperation ternaryOperation = returnStatement.getExpression(0);
    assertNotNull(ternaryOperation);
  }

  public void testNestedTernaryOperator() throws Exception {
    TranslationUnit unit = parse("int foo(int a, int b) { int c = a ? 0 : (b ? 1 : 2); }");
    FunctionDefinition functionFoo = unit.getChild(0);
    VariableDeclaration variableC = functionFoo.getChild(0);
    TernaryOperation ternaryOperation = variableC.getExpression(0);
    TernaryOperation nestedTernaryOperation = ternaryOperation.getExpression(1);
    assertNotNull(nestedTernaryOperation);
  }

  public void testFunctionCall() throws Exception {
    TranslationUnit unit = parse("void foo(int) {} void bar(int) { foo(5); }");
    FunctionDefinition functionBar = unit.getChild(1);
    ExpressionStatement expressionStatement = functionBar.getChild(0);
    FunctionInvocation callFoo = expressionStatement.getExpression(0);
    assertEquals("foo", callFoo.getName());
  }

  public void testNestedFunctionCall() throws Exception {
    TranslationUnit unit = parse(
        "int foo(int a) { return a; }             " +
        "int bar(int b) { return foo(foo(b)); }   ");
    FunctionDefinition functionBar = unit.getChild(1);
    assertEquals("bar", functionBar.getName());
    ReturnStatement returnStatement = functionBar.getChild(0);
    FunctionInvocation callFoo = returnStatement.getExpression(0);
    assertEquals("foo", callFoo.getName());
    NodeList parameters = callFoo.getParameters();
    FunctionInvocation callFooAgain = parameters.get(0);
    assertEquals("foo", callFooAgain.getName());
    assertEquals(0, callFooAgain.getChildren().size());
  }

  public void testSequentialFunctionCalls() throws Exception {
    TranslationUnit unit = parse(
        "class A { public: void foo() {} };     " +
        "A bar() { A a; return a; }             " +
        "void main() { bar().foo(); }           ");
    FunctionDefinition functionMain = unit.getChild(2);
    assertEquals("main", functionMain.getName());
    ExpressionStatement expressionStatement = functionMain.getChild(0);
    FunctionInvocation callBar = expressionStatement.getExpression(0);
    assertEquals("bar", callBar.getName());
    FunctionInvocation callFoo = callBar.getChild(0);
    assertEquals("foo", callFoo.getName());
    assertEquals(0, callFoo.getChildren().size());
  }

  public void testLocalVariable() throws Exception {
    TranslationUnit unit = parse(
        "void main() { int a = 0, b = 0; a += 1; }");
    FunctionDefinition functionMain = unit.getChild(0);
    assertEquals("main", functionMain.getName());
    VariableDeclaration variableA = functionMain.getChild(0);
    assertEquals("a", variableA.getName());
    VariableDeclaration variableB = functionMain.getChild(1);
    assertEquals("b", variableB.getName());
  }

  public void testPrivateAccessSpecifier() throws Exception {
    TranslationUnit unit = parse(
        "class A { private: void foo(); };");
    ClassDeclaration classA = unit.getChild(0);
    FunctionDeclaration functionFoo = classA.getChild(0);
    Visibility visibility = functionFoo.getVisibility();
    assertEquals(Visibility.PRIVATE, visibility);
  }

  public void testProtectedAccessSpecifier() throws Exception {
    TranslationUnit unit = parse(
        "class A { protected: void foo() {} void bar() {} };");
    ClassDeclaration classA = unit.getChild(0);
    FunctionDefinition functionFoo = classA.getChild(0);
    Visibility visibilityFoo = functionFoo.getVisibility();
    assertEquals(Visibility.PROTECTED, visibilityFoo);
    FunctionDefinition functionBar = classA.getChild(1);
    Visibility visibilityBar = functionBar.getVisibility();
    assertEquals(Visibility.PROTECTED, visibilityBar);
  }

  public void testLocalAssgnment() throws Exception {
    TranslationUnit unit = parse(
        "void main() { int a = 0, b = 1; a = b; }");
    FunctionDefinition functionMain = unit.getChild(0);
    VariableDeclaration variableA = functionMain.getChild(0);
    assertEquals("a", variableA.getName());
    VariableDeclaration variableB = functionMain.getChild(1);
    assertEquals("b", variableB.getName());
    ExpressionStatement statement = functionMain.getChild(2);
    Expression expression = statement.getExpression(0);
    assertTrue(expression instanceof AssignmentExpression);
    AssignmentExpression assignment = (AssignmentExpression) expression;
    Name leftSide = assignment.getExpression(0);
    Name rightSide = assignment.getExpression(1);
    assertEquals("a", leftSide.getIdentifier());
    assertEquals("b", rightSide.getIdentifier());
  }

  public void testPointerVariable() throws Exception {
    TranslationUnit unit = parse(
      "void main() { int *p = 0, a = 0, *pp = 0; }");
    FunctionDefinition functionMain = unit.getChild(0);
    VariableDeclaration variableP = functionMain.getChild(0);
    assertEquals("p", variableP.getName());
    assertEquals("int", variableP.getType());
    assertTrue(variableP.isPointer());
    VariableDeclaration variableA = functionMain.getChild(1);
    assertEquals("a", variableA.getName());
    assertEquals("int", variableA.getType());
    assertFalse(variableA.isPointer());
    VariableDeclaration variablePP = functionMain.getChild(2);
    assertEquals("pp", variablePP.getName());
    assertEquals("int", variablePP.getType());
    assertTrue(variablePP.isPointer());
  }

  public void testReferenceVariable() throws Exception {
    TranslationUnit unit = parse(
      "void main() { int a = 0; int& r = a; }");
    FunctionDefinition functionMain = unit.getChild(0);
    VariableDeclaration variableA = functionMain.getChild(0);
    assertEquals("a", variableA.getName());
    assertEquals("int", variableA.getType());
    assertFalse(variableA.isPointer());
    VariableDeclaration variableR = functionMain.getChild(1);
    assertEquals("r", variableR.getName());
    assertEquals("int", variableR.getType());
    assertTrue(variableR.isPointer());
  }

  public void testClassLoadCppVariables() throws Exception {
    assertEquals(64, CPPvariables.QI_TYPE.size());
  }

  public void testInheritance() throws Exception {
    TranslationUnit unit = parse("class A{}; class B : public A {};");
    ClassDeclaration classA = unit.getChild(0);
    ClassDeclaration classB = unit.getChild(1);
    assertEquals("A", classA.getName());
    assertEquals("B", classB.getName());
    ClassDeclaration baseB = classB.getBaseClass(0).getDeclaration();
    assertEquals("A", baseB.getName());
    assertEquals(AccessSpecifier.PUBLIC, classB.getBaseClass(0)
        .getAccessSpecifier());
  }

  public void testMultipleInheritence() throws Exception {
    TranslationUnit unit = parse(
        "class A{}; class B{}; class C : public A, protected B {};");
    ClassDeclaration classA = unit.getChild(0);
    ClassDeclaration classB = unit.getChild(1);
    ClassDeclaration classC = unit.getChild(2);
    assertEquals("A", classA.getName());
    assertEquals("B", classB.getName());
    assertEquals("C", classC.getName());

    BaseClass baseC0 = classC.getBaseClass(0);
    BaseClass baseC1 = classC.getBaseClass(1);

    assertEquals("A", baseC0.getDeclaration().getName());
    assertEquals(AccessSpecifier.PUBLIC, baseC0.getAccessSpecifier());

    assertEquals("B", baseC1.getDeclaration().getName());
    assertEquals(AccessSpecifier.PROTECTED, baseC1.getAccessSpecifier());
  }

  public void testInheritedClassInSpecifiedNamespace() throws Exception {
    TranslationUnit unit = parse(
      "namespace Foo { class A {}; } " +
      "class B : public Foo::A {};");
    Namespace namespaceFoo = unit.getChild(0);
    ClassDeclaration classA = namespaceFoo.getChild(0);
    ClassDeclaration classB = unit.getChild(1);
    assertEquals("Foo::A", classA.getQualifiedName());
    assertEquals("B", classB.getName());
    ClassDeclaration baseB = classB.getBaseClass(0).getDeclaration();
    assertEquals("A", baseB.getName());
    assertEquals(AccessSpecifier.PUBLIC, classB.getBaseClass(0)
        .getAccessSpecifier());
  }

  public void testInheritedClassInOtherTranslationUnit() throws Exception {
    // Build other tree with external declaration.
    NodeDictionary knownSymbols = new NodeDictionary();
    ClassDeclaration other = new ClassDeclaration("B");
    other.setParent(new Namespace("Bar"));
    knownSymbols.registerNode("Bar::B", other);

    TranslationUnit unit = parse("class A : public Bar::B {};", knownSymbols);
    ClassDeclaration classA = unit.getChild(0);
    assertEquals("A", classA.getName());

    ClassDeclaration baseA = classA.getBaseClass(0).getDeclaration();
    assertEquals("B", baseA.getName());
    assertEquals("Bar::B", baseA.getQualifiedName());
  }
}
TOP

Related Classes of com.google.test.metric.cpp.CppParserTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.