SonarQube 参数值
SonarQube Arguments value
目前我正在制定规则,该规则应检查方法是否包含@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在{}的()中时,lastToken.text()仅return)或}.
有没有办法获取 () 或 {} 中的参数值?
我明白了。我改用 FileScannerContext。
首先,我检查方法是否用@Test 和@TestInfo 注释,然后获取@TestInfo 位于哪一行。后来它只是在字符串行中找到我需要的东西。
这是我最终的工作解决方案:
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);
}
}
目前我正在制定规则,该规则应检查方法是否包含@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在{}的()中时,lastToken.text()仅return)或}.
有没有办法获取 () 或 {} 中的参数值?
我明白了。我改用 FileScannerContext。 首先,我检查方法是否用@Test 和@TestInfo 注释,然后获取@TestInfo 位于哪一行。后来它只是在字符串行中找到我需要的东西。
这是我最终的工作解决方案:
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);
}
}