package org.test4j.spec.scenario.step.txt;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;
import org.test4j.spec.annotations.Named;
public class ParameterParser {
/**
* 根据传入的测试描述文件,解析相应的变量名称和变量值
*
* @param stepWithoutStartingWord
* @return
*/
public static LinkedHashMap<String, String> parserParameter(String stepWithoutStartingWord) {
LinkedHashMap<String, String> paras = new LinkedHashMap<String, String>();
char[] words = (stepWithoutStartingWord + "\0").toCharArray();
int count = 1;
for (int index = 0; index < words.length;) {
char ch = words[index];
if (ch == '$' && words[index + 1] == '{') {
index = parseSinglePara(paras, words, index + 2, String.valueOf(count++));
}
index++;
}
return paras;
}
/**
* 解析单个变量名称和值,返回结束符所在位置
*
* @param paras
* 变量列表
* @param words
* 被解析的字符串
* @param start
* 解析开始位置
* @param defaultKey
* 默认的key name
* @return
*/
static int parseSinglePara(Map<String, String> paras, char[] words, int start, String defaultKey) {
StringBuilder buff = new StringBuilder();
int wordsIndex = start;
int equalsIndex = 0;
boolean hasQuato = false;
boolean ignoreRested = false;
for (int pos = start; pos < words.length; pos++) {
char ch = words[pos];
if (ch == '\\') {
pos++;
ch = words[pos];
buff.append(ch);
continue;
} else if (ch == '}' || ch == '\0') {
break;
}
wordsIndex = pos;
if (ignoreRested) {
continue;
}
// 当碰到'"'时,还没有'=',表示没有显式指定变量名称
if (ch == '"' && equalsIndex == 0) {
equalsIndex = -1;
if (pos == start) {
hasQuato = true;
}
} else if (ch == '=' && equalsIndex == 0) {
equalsIndex = pos - start;
if (words[pos + 1] == '"') {
hasQuato = true;
}
} else if (ch == '|') {
ignoreRested = true;
continue;
}
buff.append(ch);
}
String para = buff.toString();
String key = defaultKey;
if (equalsIndex > 0) {
key = para.substring(0, equalsIndex);
para = para.substring(equalsIndex + 1);
}
String value = para;
if (hasQuato) {
value = para.substring(1, para.length() - 1);
}
paras.put(key, value);
return wordsIndex + 1;
}
/**
* 从Spec的方法构造"methodname $paraname $paraname"字符串
*
* @param method
* @return
*/
public static String getPatternAsStringFromMethod(Method method) {
StringBuilder builder = new StringBuilder();
builder.append(method.getName());
Annotation[][] paraAnnotations = method.getParameterAnnotations();
for (int index = 0; index < paraAnnotations.length; index++) {
Annotation[] annotations = paraAnnotations[index];
String name = annotationName(annotations, index + 1);
builder.append(" ").append(name);
}
return builder.toString();
}
private static String annotationName(Annotation[] annotations, int index) {
for (Annotation annotation : annotations) {
if (annotation.annotationType().isAssignableFrom(Named.class)) {
return "$" + ((Named) annotation).value();
}
}
return "$" + index;
}
}