All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jbehaviour.impl.JBehaviourLauncher Maven / Gradle / Ivy

The newest version!
/**
 *  Copyright 2012 Yannick Roffin
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package org.jbehaviour.impl;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.jbehaviour.IBehaviourLauncher;
import org.jbehaviour.IBehaviourScenario;
import org.jbehaviour.exception.JBehaviourParsingError;
import org.jbehaviour.exception.JBehaviourRuntimeError;
import org.jbehaviour.parser.JBehaviourParser;
import org.jbehaviour.parser.model.FormalStory;
import org.jbehaviour.parser.model.IKeywordStatement;
import org.jbehaviour.parser.model.impl.KeywordReport;
import org.jbehaviour.parser.model.impl.KeywordScenario;
import org.jbehaviour.reflexion.IBehaviourEnv;
import org.jbehaviour.reflexion.IBehaviourReflexionContext;
import org.jbehaviour.reflexion.impl.JBehaviourEnv;
import org.jbehaviour.reflexion.impl.JBehaviourReflexion;
import org.jbehaviour.report.IBehaviourReport;
import org.jbehaviour.xref.impl.JBehaviourXRef;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * this class implement the main of this system
 */
public class JBehaviourLauncher implements IBehaviourLauncher {
	static Logger logger = LoggerFactory.getLogger(JBehaviourLauncher.class);
	private IBehaviourEnv env;

	private List scenarios = new ArrayList();
	private Map scenariosByName = new HashMap();
	private Stack stack = new Stack();

	/**
	 * constructor
	 * @throws JBehaviourParsingError
	 */
	public JBehaviourLauncher() throws JBehaviourParsingError {
		env = new JBehaviourEnv(this,new JBehaviourReflexion(),new JBehaviourXRef());
	}

	FormalStory parsedStory = null;

	@Override
	public IBehaviourEnv getEnv() {
		return env;
	}

	@Override
	public FormalStory getParsedStory() {
		return parsedStory;
	}

	@Override
	public boolean registerAndExecute(File story) throws JBehaviourParsingError, JBehaviourRuntimeError {
		/**
		 * story parser
		 */
		try {
			parsedStory = (new JBehaviourParser(story)).parse();
		} catch (JBehaviourParsingError e) {
			e.printStackTrace();
			return false;
		}

		/**
		 * check for report configuration
		 */
		for(IKeywordStatement item : parsedStory.getFeature().getKeywordReports()) {
			KeywordReport report = (KeywordReport) item;
			/**
			 * check for class existence
			 */
			try {
				Class.forName(report.getKlass()).newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
				throw new JBehaviourParsingError(e);
			} catch (IllegalAccessException e) {
				e.printStackTrace();
				throw new JBehaviourParsingError(e);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
				throw new JBehaviourParsingError(e);
			}
			if(!(new File(report.getTemplate()).exists())) {
				throw new JBehaviourParsingError("No template file " + report.getTemplate());
			}
		}

		/**
		 * read and execute it
		 */
		boolean result = registerAndExecuteStory(story, parsedStory);
		
		/**
		 * dump xref
		 * xref have collected all statistics elements during
		 * story run
		 */
		env.getXRef().setName(story.getName());
		for(IKeywordStatement item : parsedStory.getFeature().getKeywordReports()) {
			KeywordReport report = (KeywordReport) item;
			logger.info("Report: " + report.getKlass());
			logger.info("Template: " + report.getTemplate());
			logger.info("Output: " + report.getOutputFile());
			try {
				IBehaviourReport myReport = (IBehaviourReport) Class.forName(report.getKlass()).newInstance();
				myReport.init();
				myReport.render(env.getRef(), new File(report.getTemplate()), new File(report.getOutputFile()));
			} catch (InstantiationException e) {
				e.printStackTrace();
				return false;
			} catch (IllegalAccessException e) {
				e.printStackTrace();
				return false;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
				return false;
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}
		}

		return result;
	}
	
	@Override
	public boolean registerAndExecuteStory(File story, FormalStory parsedStory) throws JBehaviourParsingError, JBehaviourRuntimeError {
		/**
		 * reflexion manager
		 */
		for(IKeywordStatement include : parsedStory.getFeature().getKeywordInclude()) {
			/**
			 * include all this object in current
			 * transaction
			 */
			FormalStory includeStory = null;
			try {
				includeStory = (new JBehaviourParser(new File(include.getReference()))).parse();
			} catch (JBehaviourParsingError e) {
				e.printStackTrace();
				return false;
			}
			/**
			 * add all register, declare ... of this story in current
			 */
			parsedStory.getFeature().includeRegister(includeStory.getFeature().getKeywordRegister());
			parsedStory.getFeature().includeDeclare(includeStory.getFeature().getKeywordDeclare());
			for(KeywordScenario scenario : includeStory.getScenarios()) {
				parsedStory.getScenarios().add(scenario);
			}
		}
		for(IKeywordStatement register : parsedStory.getFeature().getKeywordRegister()) {
			try {
				env.getRef().register(register.getReference(),register.getKlass());
			} catch (JBehaviourParsingError e) {
				e.printStackTrace();
				return false;
			}
		}

		logger.info("Class registred: " + parsedStory.getFeature().getKeywordRegister().size());

		/**
		 * run variable declararion
		 */
		for(IKeywordStatement declare : parsedStory.getFeature().getKeywordDeclare()) {
			switch(declare.getDeclareType()) {
				case String:
					env.getRef().declareString(declare.getReference(),declare.extractLiteralAsString(3));
					break;
				case Json:
					env.getRef().declareJson(declare.getReference(),declare.extractLiteralAsString(3),declare.get(4).getValue());
					break;
				default:
					throw new JBehaviourRuntimeError("Type " + declare.getDeclareType() + " unknown" );
			}
		}

		/**
		 * now scenario by scenario execute all of them
		 */
		for(KeywordScenario parsedScenario : parsedStory.getScenarios()) {
			String key = parsedScenario.getStatement();
			if(scenariosByName.containsKey(key)) {
				logger.error("Scenario statement must be unique : " + key);
				throw new JBehaviourRuntimeError("Scenario statement must be unique : " + key);
			} else {
				IBehaviourScenario s = compile(parsedScenario);
				scenariosByName.put(key, s);
				scenarios.add(s);				
			}
		}
		/**
		 * fix calling stack
		 */
		for(IBehaviourScenario scenario : scenarios) {
			scenario.setCallers(scenarios);
		}
		/**
		 * execute all scenarios
		 */
		boolean result = true;
		for(IBehaviourScenario key : scenarios) {
			/**
			 * only primary scenario can be executed
			 * (called scenario are not directly run)
			 */
			if(key.getCallers().size() == 0) {
				result = result & executeByStatement(key.getStatement());
			}
		}
		
		/**
		 * global result
		 */
		return result;
	}

	@Override
	public IBehaviourScenario compile(KeywordScenario parsedScenario) throws JBehaviourRuntimeError {
		IBehaviourScenario scenario = new JBehaviourScenario(parsedScenario);
		IBehaviourReflexionContext context = null;
		for(IKeywordStatement step : parsedScenario.getKeywords()) {
			logger.info("Compile : " + step.getStatement());
			try {
				context = env.getRef().retrieve(parsedScenario.getTextLikeMethod(),step.getType(),step.getStatement());
			} catch (JBehaviourParsingError e) {
				e.printStackTrace();
				throw new JBehaviourRuntimeError(e);
			} catch (JBehaviourRuntimeError e) {
				e.printStackTrace();
				throw e;
			}
			/**
			 * context must be found
			 */
			if(context == null) {
				logger.error("Unable to find step " + step.getStatement());
				throw new JBehaviourRuntimeError("Unable to find step " + step.getStatement());
			} else {
				scenario.add(context);
			}
		}
		return scenario;
	}

	@Override
	public boolean execute(IBehaviourScenario scenario) throws JBehaviourRuntimeError {
		/**
		 * push this call in the call stack
		 */
		stack.push(scenario);
		try {
			logger.info("Scenario running : " + scenario.getStatement() + " / " + stack.size() + " / " + scenario.getCallers());
			if(logger.isDebugEnabled()) {
				StringBuilder sLevel = new StringBuilder();
				for(IBehaviourScenario item : stack) {
					logger.info(sLevel.toString() + "[+] " + item.getStatement());
					sLevel.append("    ");
				}
			}
			for(IBehaviourReflexionContext step : scenario.getContexts()) {
				logger.info("Step running : " + step.getStatement());
				Object ret = null;
				try {
					/**
					 * we have found this step, no we can execute
					 * it
					 */
					ret = step.execute(env);
				} catch (JBehaviourParsingError e) {
					e.printStackTrace();
					return false;
				} catch (JBehaviourRuntimeError e) {
					e.printStackTrace();
					return false;
				}
				logger.info("Result is " + ret);
				switch(step.getType()) {
					case Given:
					case Call:
					case When:
						/**
						 * Given, Call and When return value have
						 * no action on the execution
						 */
						break;
					case Then:
						/**
						 * Then statement are special statement, because
						 * return must be analyzed and checked to continue
						 * false break the scenario/story execution
						 */
						if(ret == null) {
							throw new JBehaviourRuntimeError(step.toString() + " : return on Then keyword cannot be null !!!");
						}
						if((Boolean) ret == false) return (Boolean) ret;
					default:
						break;
				}
			}
			return true;
		} finally {
			stack.pop();
		}
	}

	@Override
	public boolean executeByStatement(String name) throws JBehaviourRuntimeError {
		return execute(scenariosByName.get(name));
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy