package org.test4j.spec.scenario.step;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.test4j.spec.exceptions.SkipStepException;
import org.test4j.spec.inner.IScenarioStep;
import org.test4j.spec.inner.StepType;
import org.test4j.spec.inner.ISpecMethod.SpecMethodID;
import org.test4j.spec.util.ParaConverter;
import org.test4j.tools.commons.StringHelper;
@SuppressWarnings("serial")
public abstract class JSpecStep implements IScenarioStep, Serializable {
protected StepType type;
protected String method;
protected String initialText;
protected String displayText;
protected LinkedHashMap<String, String> paras;
protected boolean isSkip;
protected Throwable error;
protected String scenario;
protected JSpecStep(String scenario) {
this.scenario = scenario;
this.error = null;
}
@Override
public void setError(Throwable error) {
this.error = error;
}
@Override
public boolean isSuspend() {
return isSkip || (this.error instanceof SkipStepException);
}
@Override
public boolean isSuccess() {
return this.error == null;
}
@Override
public boolean isFailure() {
return this.error != null && !(this.error instanceof SkipStepException);
}
@Override
public Throwable getError() {
return this.error;
}
@Override
public Object[] getArguments(List<String> paraNameds, List<Type> paraTypes) {
List<Object> values = new ArrayList<Object>();
for (int index = 0; index < paraNameds.size(); index++) {
String paraNamed = paraNameds.get(index);
if (this.paras.containsKey(paraNamed) == false) {
String keys = StringHelper.merger(this.paras.keySet(), ',');
String error = String.format("can't find parameter %s, the existed parameters are [%s].", paraNamed,
keys);
throw new RuntimeException(error);
}
String paraValue = this.paras.get(paraNamed);
try {
Type paraType = paraTypes.get(index);
Object value = ParaConverter.convert(paraValue, paraType);
isSubType(value, paraType);
values.add(value);
} catch (Throwable e) {
String err = String.format("the json\n %s \n covert to parameter @Named(\"%s\") error:%s", paraValue,
paraNamed, e.getMessage());
throw new RuntimeException(err, e);
}
}
return values.toArray(new Object[0]);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void isSubType(Object value, Type paraType) {
Class clazType = null;
if (paraType instanceof Class) {
clazType = (Class) paraType;
} else if (paraType instanceof ParameterizedType) {
clazType = (Class) ((ParameterizedType) paraType).getRawType();
}
if (value != null && clazType != null && !clazType.isAssignableFrom(value.getClass())) {
String err = String.format("convert to type[%s] error", clazType.getName());
throw new RuntimeException(err);
}
}
/**
* 解析场景步骤的具体内容<br>
* etc: 参数, 描述等
*
* @param content
*/
public abstract void parseStep(Object content, IScenarioStep template);
@Override
public SpecMethodID getSpecMethodID() {
SpecMethodID id = new SpecMethodID(method, paras.size());
return id;
}
@Override
public StepType getType() {
return type;
}
public String getInitialText() {
return initialText;
}
@Override
public String getDisplayText() {
return displayText;
}
@Override
public String getMethod() {
return method;
}
@Override
public LinkedHashMap<String, String> getParas() {
return paras;
}
@Override
public String toString() {
return type + " method[" + method + "], skip status[" + isSkip + "]";
}
public String toTxtString() {
StringBuilder buff = new StringBuilder();
if (this.error == null) {
buff.append("\tSUCCESS ");
} else if (this.error == SkipStepException.instance) {
buff.append("\tSUSPEND ");
} else {
buff.append("\tFAILURE ");
}
buff.append(type.name()).append("\t").append(this.method);
buff.append("\n\t\t").append(this.displayText).append("\n");
if (this.error != null && this.error != SkipStepException.instance) {
buff.append("\tError:").append(this.error.getMessage()).append("\n");
}
return buff.toString();
}
public static IScenarioStep findTemplate(List<IScenarioStep> templates, String method, StepType type) {
if (templates == null || method == null || type == null) {
return null;
}
for (IScenarioStep template : templates) {
if (method.equals(template.getMethod()) && type.equals(template.getType())) {
return template;
}
}
return null;
}
/**
* 根据模板初始化参数内容
*
* @param template
* @return
*/
protected LinkedHashMap<String, String> initParameters(IScenarioStep template) {
LinkedHashMap<String, String> inits = new LinkedHashMap<String, String>();
if (template == null) {
return inits;
}
for (Map.Entry<String, String> para : template.getParas().entrySet()) {
inits.put(para.getKey(), para.getValue());
}
return inits;
}
}