Значение аргументов SonarQube - PullRequest
0 голосов
/ 18 января 2019

В настоящее время я пишу правило, которое должно проверять, содержит ли метод аннотации @Test и @TestInfo. Если это так, @TestInfo должен иметь не пустой аргумент testCaseId.

Существует несколько различных способов заполнения testCaseId. Примеры:

@Test
@TestInfo(testCaseId = { "ABC-123", "DEF-154" }, component = "Component")
public int foo() {
    return 0;
}


@Test
@TestInfo(testCaseId = ("ABC-123"), component = "Component")
public int foo() {
    return 0;
}


@Test
@TestInfo(testCaseId = "ABC-123", component = "Component")
public int foo() {
    return 0;
}

Я уже рассмотрел случаи, когда @TestInfo не существует, аргумент testCaseId отсутствует или значение testCaseId равно "".

Но мне трудно найти, как получить полное значение testCaseId.

Вот как я нахожу аргументы:

Arguments arguments = annotationTree.arguments();
if (!arguments.isEmpty()) {
    for (int i = 0; i < arguments.size(); i++) {
        checkArgument(arguments.get(i));
    }
}
if (!annotationsContainsTestCaseId) {
    reportIssue(arguments, "Method annotated with @TestInfo should have not empty testCaseId parameter");
}

private void checkArgument(ExpressionTree argument) {

    String parameter = argument.firstToken().text();
    String parameterValue = argument.lastToken().text();

    if (isParameterTestCaseId(parameter)) {
        annotationsContainsTestCaseId = true;
        if (isTestCaseIdEmpty(parameterValue)) {
            reportIssue(argument, "Method annotated with @TestInfo should have not empty testCaseId parameter");
        }
    }
}

private boolean isParameterTestCaseId(String parameter) {
    return parameter.matches("testCaseId");
}

private boolean isTestCaseIdEmpty(String parameterValue) {
    // if "" is empty, length is 2
    return parameterValue.length() == 2;
}

Но когда testCaseId находится в () of {}, lastToken.text () только возвращает) или}.

Есть ли способ получить значение аргумента в () или {}?

1 Ответ

0 голосов
/ 18 января 2019

Я понял это. Я перешел на использование FileScannerContext. Сначала я проверяю, аннотирован ли метод с помощью @Test и @TestInfo, а затем выясняю, в какой строке находится @TestInfo. Позже он просто находит то, что мне нужно в строке String.

Это мое окончательное рабочее решение:

private static final String TEST_ANNOTATION_PATH = "org.testng.annotations.Test";
private static final String TEST_INFO_ANNOTATION_PATH = "toolkit.utils.TestInfo";
private static final String REPORT_EMPTY_TEST_CASE_ID = "Method annotated with @TestInfo should have not empty testCaseId parameter";
private static final String REPORT_MISSING_TEST_INFO = "Method annotated with @Test should also be annotated with @TestInfo";
private static final String TEST_CASE_ID_SPLIT_PLACE = "testCaseId=";

private int methodStartLine = 0;
private int methodEndLine = 0;
private int annotationLine;
private String annotationLineText;

@Override
public List<Tree.Kind> nodesToVisit() {
    return ImmutableList.of(Tree.Kind.METHOD, Tree.Kind.ANNOTATION);
}

@Override
public void visitNode(Tree tree) {
    if (tree.is(Tree.Kind.METHOD)) {

        MethodTree methodTree = (MethodTree) tree;
        scanMethodTree(methodTree);

    } else if (tree.is(Tree.Kind.ANNOTATION)) {

        AnnotationTree annotationTree = (AnnotationTree) tree;
        scanAnnotationTree(annotationTree);

    }

}

private void scanMethodTree(MethodTree methodTree) {
    if (methodTree.symbol().metadata().isAnnotatedWith(TEST_ANNOTATION_PATH)) {
        if (methodTree.symbol().metadata().isAnnotatedWith(TEST_INFO_ANNOTATION_PATH)) {

            methodStartLine = methodTree.firstToken().line();
            methodEndLine = methodTree.lastToken().line();

        } else {
            reportIssue(methodTree.simpleName(), REPORT_MISSING_TEST_INFO);
        }
    }
}

private void scanAnnotationTree(AnnotationTree annotationTree) {
    if (annotationTree.symbolType().fullyQualifiedName().equals(TEST_INFO_ANNOTATION_PATH)) {

        annotationLine = annotationTree.firstToken().line();
        if (annotationLine >= methodStartLine && annotationLine < methodEndLine) {

            annotationLineText = context.getFileLines().get(annotationLine - 1).replaceAll("\\s", "");

            if (annotationLineText.contains("testCaseId")) {
                // {"ABC-123","DEF-456"} OR {("ABC-123"), ("DEF-456")}
                if ((annotationLineText.contains("{(\"") || annotationLineText.contains("{\""))
                        && (annotationLineText.contains("\")}") || annotationLineText.contains("\"}"))) {
                    reportCase1();
                }
                // ("ABC-123")
                else if (annotationLineText.contains("(\"") && annotationLineText.contains("\")")) {
                    reportCase2();
                }
                // "ABC-123"
                else if (annotationLineText.contains("\"") && annotationLineText.contains("\",")) {
                    reportCase3();
                }

            } else {
                addIssue(annotationLine, REPORT_EMPTY_TEST_CASE_ID);
            }
        }
    }
}

/**
 * Method report an issue if testCaseId = {"ABC-123","DEF-456",...,"AEF-159"} or
 * testCaseId = {("ABC-123"),("DEF-456"),...,("AEF-159")} has no values between
 * quotes.
 */
private void reportCase1() {
    String testCaseId = annotationLineText.split(TEST_CASE_ID_SPLIT_PLACE)[1].split("}")[0];
    testCaseId = testCaseId.replaceAll("\"", "").replaceAll("\\{", "").replaceAll(",", "").replaceAll("\\(", "")
            .replaceAll("\\)", "");

    if (testCaseId.length() == 0) {
        addIssue(annotationLine, REPORT_EMPTY_TEST_CASE_ID);
    }
}

/**
 * Method report an issue if testCaseId = ("ABC-123") has no value between
 * quotes.
 */
private void reportCase2() {
    String testCaseId = annotationLineText.split(TEST_CASE_ID_SPLIT_PLACE)[1].split("\"\\)")[0];
    testCaseId = testCaseId.replaceAll("\"", "").replaceAll("\\(", "").replaceAll(",", "");

    if (testCaseId.length() == 0) {
        addIssue(annotationLine, REPORT_EMPTY_TEST_CASE_ID);
    }
}

/**
 * Method report an issue if testCaseId = "ABC-123" has no value between quotes.
 */
private void reportCase3() {
    String testCaseId = annotationLineText.split(TEST_CASE_ID_SPLIT_PLACE)[1].split("\",")[0];
    testCaseId = testCaseId.replaceAll("\"", "").replaceAll(",", "");

    if (testCaseId.length() == 0) {
        addIssue(annotationLine, REPORT_EMPTY_TEST_CASE_ID);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...