
de.rwth.swc.coffee4j.model.InputParameterModel Maven / Gradle / Ivy
package de.rwth.swc.coffee4j.model;
import de.rwth.swc.coffee4j.engine.util.Preconditions;
import de.rwth.swc.coffee4j.model.constraints.Constraint;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* An representation of a input parameter model for combinatorial testing. Consists of a testing strength,
* readable name for identification, parameter, and forbidden and error constraints.
* This model defines all important aspects of one combinatorial test.
*/
public final class InputParameterModel {
private final int strength;
private final String name;
private final List parameters;
private final List forbiddenConstraints;
private final List errorConstraints;
/**
* Creates a new model with no constraints.
*
* @param strength the testing strength. Must be at least one and at most the number of parameters
* @param name the name of the model. Should be human readable. Must not be {@code null}
* @param parameters all parameters of the model. Must not be, nor contain {@code null} and must not be empty.
* Must not contain parameters with duplicate names
*/
public InputParameterModel(int strength, String name, List parameters) {
this(strength, name, parameters, Collections.emptyList(), Collections.emptyList());
}
/**
* Creates a new model with all given configuration arguments.
*
* @param strength the testing strength. Must be at least one and at most the number of parameters
* @param name the name of the model. Should be human readable. Must not be {@code null}
* @param parameters all parameters of the model. Must not be, nor contain {@code null} and must not be empty.
* @param forbiddenConstraints all constraints which may never be violated as test inputs won't work then
* May not be, nor contain {@code null}
* @param errorConstraints all constraints which may be violated but will cause the system to throw an exception.
* * All in all describes input which should not be allowed.
* May not be, nor contain {@code null}
*/
public InputParameterModel(int strength, String name, List parameters, Collection forbiddenConstraints, Collection errorConstraints) {
Preconditions.notNull(name);
Preconditions.notNull(parameters);
Preconditions.notNull(forbiddenConstraints);
Preconditions.notNull(errorConstraints);
Preconditions.check(strength > 0);
Preconditions.check(strength <= parameters.size());
Preconditions.check(!parameters.contains(null));
Preconditions.check(!forbiddenConstraints.contains(null));
Preconditions.check(!errorConstraints.contains(null));
checkParameterDoesNotContainDuplicateName(parameters);
this.strength = strength;
this.name = name;
this.parameters = new ArrayList<>(parameters);
this.forbiddenConstraints = new ArrayList<>(forbiddenConstraints);
this.errorConstraints = new ArrayList<>(errorConstraints);
}
private static void checkParameterDoesNotContainDuplicateName(List parameters) {
final Set parameterNames = new HashSet<>();
for (Parameter parameter : parameters) {
final String parameterName = parameter.getName();
if (parameterNames.contains(parameterName)) {
throw new IllegalArgumentException("Parameter name " + parameterName + " appears twice");
}
parameterNames.add(parameterName);
}
}
/**
* @return the testing strength
*/
public int getStrength() {
return strength;
}
/**
* @return the descriptive name of the model
*/
public String getName() {
return name;
}
/**
* @return a copy of the list of all parameters of this model
*/
public List getParameters() {
return Collections.unmodifiableList(parameters);
}
/**
* @return a copy of the list of all forbidden constraints. Test inputs may never violate those constraints as they
* define combinations which are not possible testable (like testing safari on windows is not possible)
*/
public List getForbiddenConstraints() {
return Collections.unmodifiableList(forbiddenConstraints);
}
/**
* @return a copy of the list of all error constraints. Test inputs may violate these constraints but they define
* inputs on which the system under test should react in a destructive way like raising exception
* (like trying to parse "asfd" as a number)
*/
public List getErrorConstraints() {
return Collections.unmodifiableList(errorConstraints);
}
/**
* @return the number of parameters
*/
public int size() {
return parameters.size();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final InputParameterModel model = (InputParameterModel) o;
return strength == model.strength && Objects.equals(name, model.name) && Objects.equals(parameters, model.parameters) && Objects.equals(forbiddenConstraints, model.forbiddenConstraints) && Objects.equals(errorConstraints, model.errorConstraints);
}
@Override
public int hashCode() {
return Objects.hash(strength, name, parameters, forbiddenConstraints, errorConstraints);
}
@Override
public String toString() {
return "InputParameterModel{" + "strength=" + strength + ", name='" + name + '\'' + ", parameters=" + parameters + ", forbiddenConstraints=" + forbiddenConstraints + ", errorConstraints=" + errorConstraints + '}';
}
public static Builder inputParameterModel(String name) {
return new Builder(name);
}
/**
* Realization of the builder pattern for constructing a {@link InputParameterModel}. Entry point is
* {@link #inputParameterModel(String)}.
*/
public static final class Builder {
private int strength = 1;
private String name;
private final List parameters = new ArrayList<>();
private final List forbiddenConstraints = new ArrayList<>();
private final List errorConstraints = new ArrayList<>();
private Builder(String name) {
this.name = name;
}
/**
* Stets the testing strength. Default is one.
*
* @param strength the testing strength
* @return this
*/
public Builder strength(int strength) {
this.strength = strength;
return this;
}
/**
* Sets the name. This may not be {@code null} when {@link #build()} is called.
*
* @param name a descriptive name for the model
* @return this
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* Adds a parameter to the model.
*
* @param parameter the parameter. Must not be {@code null}
* @return this
*/
public Builder parameter(Parameter parameter) {
Preconditions.notNull(parameter);
parameters.add(parameter);
return this;
}
/**
* Adds the parameter builders to the model by building them. This is a convenience method as now the user
* does not have to call {@link Parameter.Builder#build()} himself, therefore creating more readable code.
*
* @param parameter the parameter to be build. Must not be {@code null}
* @return this
*/
public Builder parameter(Parameter.Builder parameter) {
Preconditions.notNull(parameter);
parameters.add(parameter.build());
return this;
}
/**
* Adds all parameters to the model.
*
* @param parameters all parameters to be added. Must not be, nor contain {@code null}
* @return this
*/
public Builder parameters(Parameter... parameters) {
Preconditions.notNull(parameters);
for (Parameter parameter : parameters) {
parameter(parameter);
}
return this;
}
/**
* Builds all given builders and adds the result parameters to the model.
*
* @param parameters the parameters to be added. Must not be, nor contain {@code null}
* @return this
*/
public Builder parameters(Parameter.Builder... parameters) {
Preconditions.notNull(parameters);
for (Parameter.Builder parameter : parameters) {
parameter(parameter);
}
return this;
}
/**
* Adds a forbidden constraint to the model.
*
* @param forbiddenConstraint the forbidden constraint to be added. Must not be {@code null}
* @return this
*/
public Builder forbiddenConstraint(Constraint forbiddenConstraint) {
Preconditions.notNull(forbiddenConstraint);
forbiddenConstraints.add(forbiddenConstraint);
return this;
}
/**
* Adds all forbidden constraints to the model.
*
* @param forbiddenConstraints the forbidden constraints to be added. Must not be, nor contain {@code null}
* @return this
*/
public Builder forbiddenConstraints(Constraint... forbiddenConstraints) {
Preconditions.notNull(forbiddenConstraints);
for (Constraint constraint : forbiddenConstraints) {
forbiddenConstraint(constraint);
}
return this;
}
/**
* Adds a error constraint to the model.
*
* @param errorConstraint the error constraint to be added. Must not be {@code null}
* @return this
*/
public Builder errorConstraint(Constraint errorConstraint) {
Preconditions.notNull(errorConstraint);
errorConstraints.add(errorConstraint);
return this;
}
/**
* Adds all error constraints to the model.
*
* @param errorConstraints the error constraints to be added. Must not be, nor contain {@code null}
* @return this
*/
public Builder errorConstraints(Constraint... errorConstraints) {
Preconditions.notNull(errorConstraints);
for (Constraint constraint : errorConstraints) {
errorConstraint(constraint);
}
return this;
}
/**
* Builds the model. Add least one parameter needs to have been added by now.
*
* @return the constructed model
*/
public InputParameterModel build() {
return new InputParameterModel(strength, name, parameters, forbiddenConstraints, errorConstraints);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy