/** * Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite * contributors * * This file is part of EvoSuite. * * EvoSuite is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3.0 of the License, or * (at your option) any later version. * * EvoSuite is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>. */ /** * */ package org.evosuite.contracts; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.evosuite.Properties; import org.evosuite.testcase.statements.Statement; import org.evosuite.testcase.TestCase; import org.evosuite.testcase.variable.VariableReference; import org.evosuite.testcase.execution.Scope; import org.evosuite.testcase.execution.TestCaseExecutor; import org.evosuite.testcase.statements.ConstructorStatement; import org.evosuite.testcase.statements.FieldStatement; import org.evosuite.testcase.statements.MethodStatement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Based on ObjectContract / Randoop * * @author Gordon Fraser */ public abstract class Contract { protected static final Logger logger = LoggerFactory.getLogger(Contract.class); protected static class Pair<T> { T object1; T object2; public Pair(T o1, T o2) { object1 = o1; object2 = o2; } } /** * <p> * getAllObjects * </p> * * @param scope * a {@link org.evosuite.testcase.execution.Scope} object. * @return a {@link java.util.Collection} object. */ protected Collection<Object> getAllObjects(Scope scope) { // TODO: Assignable classes and subclasses? final Class<?> targetClass = Properties.getTargetClassAndDontInitialise(); return scope.getObjects(targetClass); } protected Collection<VariableReference> getAllVariables(Scope scope) { final Class<?> targetClass = Properties.getTargetClassAndDontInitialise(); return scope.getElements(targetClass); } /** * <p> * getAllObjectPairs * </p> * * @param scope * a {@link org.evosuite.testcase.execution.Scope} object. * @return a {@link java.util.Collection} object. */ protected Collection<Pair<Object>> getAllObjectPairs(Scope scope) { Set<Pair<Object>> pairs = new HashSet<Pair<Object>>(); Class<?> targetClass = Properties.getTargetClassAndDontInitialise(); for (Object o1 : scope.getObjects(targetClass)) { for (Object o2 : scope.getObjects(o1.getClass())) { pairs.add(new Pair<Object>(o1, o2)); } } return pairs; } protected Collection<Pair<VariableReference>> getAllVariablePairs(Scope scope) { Set<Pair<VariableReference>> pairs = new HashSet<Pair<VariableReference>>(); final Class<?> targetClass = Properties.getTargetClassAndDontInitialise(); List<VariableReference> objects = scope.getElements(targetClass); for (int i = 0; i < objects.size(); i++) { for (int j = i; j < objects.size(); j++) { pairs.add(new Pair<VariableReference>(objects.get(i), objects.get(j))); } } // for (VariableReference o1 : scope.getElements(Properties.getTargetClass())) { // for (VariableReference o2 : scope.getElements(o1.getVariableClass())) { // pairs.add(new Pair<VariableReference>(o1, o2)); // } // } return pairs; } /** * Check if this statement is related to the unit under test * * @param statement * a {@link org.evosuite.testcase.statements.Statement} object. * @return a boolean. */ protected boolean isTargetStatement(Statement statement) { //if (statement.getReturnClass().equals(Properties.getTargetClass())) // return true; if (statement instanceof MethodStatement) { MethodStatement ms = (MethodStatement) statement; final Class<?> targetClass = Properties.getTargetClassAndDontInitialise(); if (targetClass.equals(ms.getMethod().getDeclaringClass())) return true; } else if (statement instanceof ConstructorStatement) { ConstructorStatement cs = (ConstructorStatement) statement; final Class<?> targetClass = Properties.getTargetClassAndDontInitialise(); if (targetClass.equals(cs.getConstructor().getDeclaringClass())) return true; } else if (statement instanceof FieldStatement) { FieldStatement fs = (FieldStatement) statement; final Class<?> targetClass = Properties.getTargetClassAndDontInitialise(); if (targetClass.equals(fs.getField().getDeclaringClass())) return true; } return false; } /** * Run the test against this contract and determine whether it reports a * failure * * @param test * a {@link org.evosuite.testcase.TestCase} object. * @return a boolean. */ public boolean fails(TestCase test) { ContractChecker.setActive(false); TestCaseExecutor executor = TestCaseExecutor.getInstance(); SingleContractChecker checker = new SingleContractChecker(this); executor.addObserver(checker); TestCaseExecutor.runTest(test); executor.removeObserver(checker); //ContractChecker.setActive(true); return !checker.isValid(); } /** * Check the contract on the current statement in the current scope * * @param statement * a {@link org.evosuite.testcase.statements.Statement} object. * @param scope * a {@link org.evosuite.testcase.execution.Scope} object. * @param exception * a {@link java.lang.Throwable} object. * @return a boolean. */ public abstract ContractViolation check(Statement statement, Scope scope, Throwable exception); /** * Add an assertion to the statement based on the contract. The assertion * should fail on a contract violation, and pass if the contract is * satisfied. * * @param statement * @param variables * @param exception */ public abstract void addAssertionAndComments(Statement statement, List<VariableReference> variables, Throwable exception); public void changeClassLoader(ClassLoader classLoader) { // No-op by default } }