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

com.ecfeed.junit.runner.UserInputHelper Maven / Gradle / Ivy

Go to download

An open library used to connect to the ecFeed service. It can be also used as a standalone testing tool. It is integrated with Junit5 and generates a stream of test cases using a selected algorithm (e.g. Cartesian, N-Wise). There are no limitations associated with the off-line version but the user cannot access the on-line computation servers and the model database.

The newest version!
package com.ecfeed.junit.runner;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import com.ecfeed.core.generators.api.GeneratorException;
import com.ecfeed.core.model.AbstractParameterNode;
import com.ecfeed.core.model.ChoiceNode;
import com.ecfeed.core.model.ClassNode;
import com.ecfeed.core.model.Constraint;
import com.ecfeed.core.model.FixedChoiceValueFactory;
import com.ecfeed.core.model.IConstraint;
import com.ecfeed.core.model.MethodNode;
import com.ecfeed.core.model.MethodParameterNode;
import com.ecfeed.core.model.ModelConverter;
import com.ecfeed.core.model.ModelOperationException;
import com.ecfeed.core.model.RootNode;
import com.ecfeed.core.model.TestCaseNode;
import com.ecfeed.core.model.serialization.ModelParser;
import com.ecfeed.core.model.serialization.ParserException;
import com.ecfeed.junit.utils.Localization;

public class UserInputHelper {
	
	private static FixedChoiceValueFactory fFactory = new FixedChoiceValueFactory(null, false);
	
	public static MethodNode getMethodNodeFromEcFeedModel(Method testMethod, String modelPath, Optional testName) throws GeneratorException {
		RootNode model = loadEcFeedModelFromDirectory(modelPath);
		List modelMethods = new ArrayList<>();
		
		for (ClassNode classNode : model.getClasses()) {
			for (MethodNode methodNode : classNode.getMethods()) {
				if (isMethodIdentical(testMethod, testName, methodNode)) {
					modelMethods.add(methodNode);
				}
			}
		}
		
		if (modelMethods.size() == 0) {
			GeneratorException.report(Localization.bundle.getString("userInputHelperMissingMethod"));
		}
		
		if (modelMethods.size() > 1) {
			GeneratorException.report(Localization.bundle.getString("userInputHelperMultipleMethod"));
		}
		
		return modelMethods.get(0);
	}
	
	public static List> getChoicesFromEcFeedModel(MethodNode methodNode, Optional choiceRestrictions) throws GeneratorException {
		List> generatorChoices = new ArrayList<>();
		List modelMethodParameters = methodNode.getMethodParameters();
		Map> modelMethodRestrictions = getChoiceRestrictionsFromUserInput(choiceRestrictions);
		
		validateChoiceRestrictionName(methodNode, modelMethodRestrictions);
		
		for (MethodParameterNode parameter : modelMethodParameters) {
			generatorChoices.add(adjustMethodParameter(parameter, adjustChoicesUsingRestrictions(parameter, modelMethodRestrictions)));
		}
		
		return generatorChoices;
	}
	
	public static List> getTestsFromEcFeedModel(MethodNode methodNode, Optional testCases) throws GeneratorException {
		List> testSuiteCollection = new ArrayList<>();
		 
		if (testCases.isPresent()) {
			Object testObject = testCases.get();
			List testSuite;
			
			if (testObject instanceof String) {
				testSuite = getTestSuiteFromEcFeedModelString(methodNode, (String) testObject);
			} else if (testObject instanceof List) {
				testSuite = getTestSuiteFromEcFeedModelList(methodNode, (List) testObject);
			} else {
				GeneratorException.report(Localization.bundle.getString("userInputHelperUnknownTest"));
				return null;
			}
			
			for (TestCaseNode node : testSuite) {
				testSuiteCollection.add(adjustChoiceNode(node.getTestData()));
			}
			
			return testSuiteCollection;
		} else {
			return new ArrayList<>();
		}
		
	}
	
	public static List> getConstraintsFromEcFeedModel(MethodNode methodNode, Optional constraintName) throws GeneratorException {
		
		if (constraintName.isPresent()) {
			Object constraintObject = constraintName.get();
			
			if (constraintObject instanceof String) {
				return getConstraintsFromEcFeedModelString(methodNode, (String) constraintObject);
			} else if (constraintObject instanceof List) {
				return getConstraintsFromEcFeedModelList(methodNode, (List) constraintObject);
			} else {
				GeneratorException.report(Localization.bundle.getString("userInputHelperUnknownConstraint"));
				return null;
			}
			
		} else {
			return new ArrayList<>();
		}

	}
	 
	private static List adjustMethodParameter(MethodParameterNode parameter, List choices) {
		List choiceList = new ArrayList<>();
		
		if (parameter.isExpected()) {
		    ChoiceNode choice = new ChoiceNode("[e]" + parameter.getDefaultValue(), null, parameter.getDefaultValue());
		    choice.setParent(parameter);

		    choiceList.add(choice);

		    return adjustChoiceNode(choiceList);
		}
		
		choiceList.addAll(choices);

		return adjustChoiceNode(choiceList);
	}
	
	private static List adjustChoiceNode(List choiceNodeList) {
		List choiceList = new ArrayList<>();
		
		for (ChoiceNode choice : choiceNodeList) {
			
			if (choice.isRandomizedValue() == false) {
				choice.setValueString(fFactory.createValue(choice) + "");
			}

			choiceList.add(choice);
		}
		
		return choiceList;
	}

	private static boolean isMethodIdentical(Method test, Optional remoteName, MethodNode model) {
		
		if (remoteName.isPresent()) {

			if (test == null) {
				return remoteName.get().equals(model.getLongSignature());
			}

			String nameModel =  ((ClassNode) model.getParent()).getFullName() + "." + model.getFullName();

			return nameModel.equals(remoteName.get()) && isMethodParameterListIdentical(test, model);
		}
		
		return isMethodClassNameIdentical(test, model) && isMethodNameIdentical(test, model);
	}
	
	private static boolean isMethodClassNameIdentical(Method test, MethodNode model) {
		String classTest = test.getDeclaringClass().getCanonicalName();
		String classModel = ((ClassNode) model.getParent()).getFullName();		
		
		return classTest.equals(classModel);
	}

 	private static boolean isMethodNameIdentical(Method test, MethodNode model) {
		String nameTest = test.getName();
		String nameModel = model.getFullName();
		
		if (nameTest.equals(nameModel)) {
			return isMethodParameterListIdentical(test, model);
		}
		
		return false;
	}
	
	private static boolean isMethodParameterListIdentical(Method test, MethodNode model) {
		Parameter[] parameterListTest = test.getParameters();
		List parameterListModel = model.getParameters();
		
		if (parameterListTest.length != parameterListModel.size()) {
			return false;
		}
		
		for (int i = 0 ; i < parameterListTest.length ; i++) {
			String parsedName = parameterListModel.get(i).getType();
			
			if (parsedName.equals("String")) {
				parsedName = "java.lang.String";
			}
			
			if (parameterListTest[i].getType().getCanonicalName().equals(parsedName)) {
				continue;
			}
			
			return false;
		}
		
		return true;
	}

	private static List getTestSuiteFromEcFeedModelString(MethodNode methodNode, String testData) throws GeneratorException {
		
		if (testData.equals("ALL")) {
			return methodNode.getTestCases();
		} else if (testData.equals("NONE")) {
			return new ArrayList<>();
		} else {
			GeneratorException.report(Localization.bundle.getString("userInputHelperUnknownTestString"));
			return null;
		}
	}
	
	private static List getTestSuiteFromEcFeedModelList(MethodNode methodNode, List testData) throws GeneratorException {
		List testSuite = new ArrayList<>();
		
		for (Object testSuiteObject : testData) {
			if (!testSuite.addAll(methodNode.getTestCases(testSuiteObject.toString()))) {
				GeneratorException.report(Localization.bundle.getString("userInputHelperWrongTestSuite") + testSuiteObject.toString());
			}
			
		}
		
		return testSuite;
	}
	
	private static List> getConstraintsFromEcFeedModelString(MethodNode methodNode, String constraintData) throws GeneratorException {

		if (constraintData.equals("ALL")) {
			return methodNode.getAllConstraints();
		} else if (constraintData.equals("NONE")) {
			return new ArrayList<>();
		} else {
			GeneratorException.report(Localization.bundle.getString("userInputHelperUnknownConstraintString"));
			return null;
		}
		
	}
	
	private static List> getConstraintsFromEcFeedModelList(MethodNode methodNode, List constraintData) throws GeneratorException {
		List> constraint = new ArrayList<>();
		List> constraintList = new ArrayList<>();
		
		for (Object constraintObject : constraintData) {
			for (IConstraint constraintMethod : methodNode.getAllConstraints()) {
				if (((Constraint) constraintMethod).getName().equals(constraintObject.toString())) {
					constraintList.add(constraintMethod);
				}
			}
			
			if (constraintList.size() == 0) {
				GeneratorException.report(Localization.bundle.getString("userInputHelperWrongConstraintSuite") + constraintObject.toString());
			}
				
			constraint.addAll(constraintList);
			constraintList.clear();
		}
		
		return constraint;
	}
	
	private static Map> getChoiceRestrictionsFromUserInput(Optional choiceRestrictions) throws GeneratorException {
		
		if (choiceRestrictions.isPresent()) {
			Object choiceRestrictionObject = choiceRestrictions.get();
			
			if (choiceRestrictionObject instanceof String) {
				return getChoiceRestrictionsFromUserInputString((String) choiceRestrictionObject);
			} else if (choiceRestrictionObject instanceof Map) {
				return getChoiceRestrictionsFromUserInputMap((Map) choiceRestrictionObject);
			} else {
				GeneratorException.report(Localization.bundle.getString("userInputHelperUnknownInput"));
				return null;
			}
			
		} else {
			return new HashMap<>();
		}
		
	}
	
	private static Map> getChoiceRestrictionsFromUserInputString(String testData) throws GeneratorException {
		
		if (testData.equals("NONE")) {
			return new HashMap<>();
		} else {
			GeneratorException.report(Localization.bundle.getString("userInputHelperUnknownInputString"));
			return null;
		}
	}
	
	@SuppressWarnings("unchecked")
	private static Map> getChoiceRestrictionsFromUserInputMap(Map testMap) throws GeneratorException {
		return (Map>) testMap;
	}
	 
	private static List adjustChoicesUsingRestrictions(MethodParameterNode parameter, Map> mapRestrictions) {
		
		List choiceListUser = mapRestrictions.get(parameter.getFullName());
		List choiceListParameter = extractChoices(new ArrayList<>(), parameter.getChoices());
		
		if (choiceListUser != null) {
			List choiceListAdjusted = new ArrayList<>();
			
			for (String choiceUser : choiceListUser) {
				for (ChoiceNode choiceParameter : choiceListParameter) {		
					if (compareChoiceName(choiceParameter.getQualifiedName(), choiceUser)) {
						choiceListAdjusted.add(choiceParameter);
					}
				}
				
			}
			
			return choiceListAdjusted;
		}

		return choiceListParameter;
	}
	
	private static List extractChoices(List compound, List choiceNodeList) {
		
		for (ChoiceNode node : choiceNodeList) {
			
			if (node.getChoices().size() != 0) {
				extractChoices(compound, node.getChoices());
				continue;
			}
			
			compound.add(node);
		}
		
		return compound;
	}
	
	private static boolean compareChoiceName(String choiceParameter, String choiceUser) {
		String[] choiceSplitParameter = choiceParameter.split(":");
		String[] choiceSplitUser = choiceUser.split(":");
		
		for (int i = 0 ; i < choiceSplitUser.length ; i++) {
			if (choiceSplitParameter[i].equals(choiceSplitUser[i])) {
				continue;
			}
			
			return false;
		}
		
		return true;
	}
	
	private static void validateChoiceRestrictionName(MethodNode methodNode, Map> userRestriction) throws GeneratorException {
		Set parameterNames = new HashSet<>(methodNode.getParametersNames());
		
		for (String key : userRestriction.keySet()) {
			if (parameterNames.contains(key)) {
				validateChoiceRestrictionArgument(methodNode.getMethodParameter(key), userRestriction.get(key));
			} else {
				GeneratorException.report(Localization.bundle.getString("userInputHelperWrongInputArgumentName") + key);
			}
		}
	}
	
	private static void validateChoiceRestrictionArgument(MethodParameterNode parameter, List userRestrictionParameter) throws GeneratorException {
		List choiceListParameter = extractChoices(new ArrayList<>(), parameter.getChoices());
		
		choiceRestrictionLoop:
		for (String choiceUser : userRestrictionParameter) {
			for (ChoiceNode choiceParameter : choiceListParameter) {		
				if (compareChoiceName(choiceParameter.getQualifiedName(), choiceUser)) {
					continue choiceRestrictionLoop;
				}
			}
			
			GeneratorException.report(Localization.bundle.getString("userInputHelperWrongInputChoiceName") + choiceUser);
		}
			
	}
	
 	private static RootNode loadEcFeedModelFromDirectory(String path) throws GeneratorException {
		InputStream modelStream = null;
		
		try {
			modelStream = Files.newInputStream(Paths.get(path));
		} catch (IOException e) {
			GeneratorException.report(Localization.bundle.getString("userInputHelperWrongModel"));
		}
		
		RootNode model = null;
		
		try {
			ModelParser modelParser = new ModelParser();
			
			model = modelParser.parseModel(modelStream, null, new ArrayList());
			model = ModelConverter.convertToCurrentVersion(model);
		} catch (ParserException e) {
			GeneratorException.report(Localization.bundle.getString("userInputHelperWrongModelParser"));
		} catch (ModelOperationException e) {
			GeneratorException.report(Localization.bundle.getString("userInputHelperWrongModelOperation"));
		}
		
		return model;
	}
 	
}