package org.test4j.spec.scenario;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.test4j.spec.inner.IScenario;
import org.test4j.spec.inner.IScenarioStep;
import org.test4j.spec.scenario.step.JSpecStep;
import org.test4j.spec.scenario.step.XmlJSpecStep;
import org.test4j.spec.scenario.step.XmlJSpecStep.XmlJSpecStepTemplate;
import org.test4j.spec.scenario.xmlparser.StoryQName;
import org.test4j.tools.commons.StringHelper;
import ext.test4j.apache.commons.io.IOUtils;
/**
* XML文件描述的故事场景解析器
*
* @author darui.wudr 2012-6-28 下午3:26:51
*/
@SuppressWarnings("unchecked")
public class XmlJSpecScenario extends JSpecScenario {
public XmlJSpecScenario(Element scenarioNode, List<IScenarioStep> templates) {
this.parse(scenarioNode, templates);
}
/**
* 解析场景节点
*
* @param scenarioNode
* @param templates
*/
private void parse(Element scenarioNode, List<IScenarioStep> templates) {
this.scenario = scenarioNode.attributeValue(StoryQName.attrName);
if (StringHelper.isBlankOrNull(this.scenario)) {
this.scenario = "default scenario";
}
this.isSkip = "true".equalsIgnoreCase(scenarioNode.attributeValue(StoryQName.attrSkip, "false").trim());
Node descNode = scenarioNode.selectSingleNode(StoryQName.nodeScenarioDescription);
this.description = descNode == null ? "" : descNode.getText();
List<Element> methodNodes = scenarioNode.selectNodes(StoryQName.nodeScenarioMethod);
for (Element methodNode : methodNodes) {
JSpecStep jspecStep = new XmlJSpecStep(this.scenario, methodNode, templates);
this.steps.add(jspecStep);
}
}
private static Story parseJSpecScenarioFrom(Document document) {
List<IScenario> scenarios = new ArrayList<IScenario>();
List<IScenarioStep> templates = parseJSpecTemplate(document);
List<Element> scenarioNodes = document.selectNodes(StoryQName.xpathScenario);
for (Element scenarioNode : scenarioNodes) {
JSpecScenario scenario = new XmlJSpecScenario(scenarioNode, templates);
scenarios.add(scenario);
}
Story story = new Story();
story.setScenarios(scenarios);
return story;
}
/**
* 从文档中解析模板步骤
*
* @param document
* @return
*/
private static List<IScenarioStep> parseJSpecTemplate(Document document) {
List<IScenarioStep> templates = new ArrayList<IScenarioStep>();
List<Element> templateNodes = document.selectNodes(StoryQName.xpathTemplateMethod);
for (Element templateNode : templateNodes) {
JSpecStep template = new XmlJSpecStepTemplate(templateNode);
templates.add(template);
}
return templates;
}
/***
* 从文本流中解析需要运行的测试场景
*
* @param is
* @param encoding 文本流编码,如果为null,则自动获取,如果自动获取失败,则使用默认编码
* @return
*/
public static Story parseJSpecScenarioFrom(InputStream is, String encoding) {
try {
SAXReader reader = new SAXReader();
if (StringHelper.isEmpty(encoding) == false) {
reader.setEncoding(encoding);
}
Document document = reader.read(is);
Story story = parseJSpecScenarioFrom(document);
return story;
} catch (Exception e) {
throw new RuntimeException("parse story xml file error.", e);
} finally {
IOUtils.closeQuietly(is);
}
}
/**
* 从文本流中解析需要运行的测试场景
*
* @param xml
* @param encoding
* @return
*/
public static Story parseJSpecScenarioFrom(String xml, String encoding) {
StringReader strReader = new StringReader(xml);
try {
SAXReader reader = new SAXReader();
if (StringHelper.isEmpty(encoding) == false) {
reader.setEncoding(encoding);
}
Document document = reader.read(strReader);
Story story = parseJSpecScenarioFrom(document);
return story;
} catch (Exception e) {
throw new RuntimeException("parse story xml file error.", e);
} finally {
strReader.close();
}
}
}