/*******************************************************************************
* Copyright 2014 JHC Systems Limited
*
* 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 jhc.redsniff.internal.expectations;
import static jhc.redsniff.core.Describer.newDescription;
import static jhc.redsniff.internal.expectations.ExpectationCheckResult.unsatisfactoryResult;
import static jhc.redsniff.util.Util.failWith;
import java.util.List;
import jhc.redsniff.internal.core.Quantity;
import org.hamcrest.Description;
import org.hamcrest.StringDescription;
import com.google.common.collect.Lists;
public class DefaultExpectationChecker<EX, QX extends Quantity<EX>, C> extends ExpectationChecker<C> {
private final List<FindingExpectation<EX,QX, C>> whenNotMetChecks=Lists.<FindingExpectation<EX,QX, C>> newArrayList();
private final List<FindingExpectation<EX,QX, C>> preChecks=Lists.<FindingExpectation<EX,QX, C>> newArrayList();
private final ExpectationChecker<C> simpleCheckerForContext;
public DefaultExpectationChecker(C context) {
super(context);
this.simpleCheckerForContext = checkerFor(context);
}
public void addUltimateCauseExpectationCheck(FindingExpectation<EX,QX, C> defaultExpectation){
whenNotMetChecks.add(defaultExpectation);
}
public void addPreCheck(FindingExpectation<EX,QX, C> defaultExpectation){
preChecks.add(defaultExpectation);
}
@Override
public <E, Q extends Quantity<E>> ExpectationCheckResult<E, Q> resultOfChecking(
FindingExpectation<E, Q, C> actualExpectationBeingChecked) {
assertPreChecks(actualExpectationBeingChecked);
ExpectationCheckResult<E, Q> resultOfCheckingActualExpectation = super.resultOfChecking(actualExpectationBeingChecked);
if(!resultOfCheckingActualExpectation.meetsExpectation())
return checkForUltimateCause(resultOfCheckingActualExpectation);
else
return resultOfCheckingActualExpectation;
}
private <E, Q extends Quantity<E>> void assertPreChecks(
FindingExpectation<E, Q, C> actualExpectationBeingChecked) {
ExpectationCheckResult<EX, QX> preCheckResult= resultOfCheckingAll(preChecks);
if(!preCheckResult.meetsExpectation()){
failWith(newDescription().appendText("While expecting: ")
.appendDescriptionOf(actualExpectationBeingChecked)
.appendText("\n")
.appendDescriptionOf(preCheckResult));
}
}
public void assertNoUltimateCauseWhile(Description activityDescription){
ExpectationCheckResult<EX, QX> resultOfCheckingForUltimateCause = resultOfCheckingAll(whenNotMetChecks);
if(!resultOfCheckingForUltimateCause.meetsExpectation())
failWith(newDescription().appendText("While ")
.appendText(activityDescription.toString())
.appendText("\n")
.appendDescriptionOf(resultOfCheckingForUltimateCause));
}
private <E, Q extends Quantity<E>> ExpectationCheckResult<E, Q> checkForUltimateCause(
ExpectationCheckResult<E, Q> resultOfCheckingActualExpectation) {
ExpectationCheckResult<EX, QX> resultOfCheckingForUltimateCause = resultOfCheckingAll(whenNotMetChecks);
if(!resultOfCheckingForUltimateCause.meetsExpectation())
return resultFor(resultOfCheckingForUltimateCause);
else
return resultOfCheckingActualExpectation;
}
private <E, Q extends Quantity<E>> ExpectationCheckResult<E, Q> resultFor(
ExpectationCheckResult<EX, QX> resultOfCheckingDefaultExpectations) {
{
StringDescription dissatisfactionDescription = new StringDescription();
dissatisfactionDescription
.appendDescriptionOf(resultOfCheckingDefaultExpectations);
return unsatisfactoryResult(null, dissatisfactionDescription);
}
}
private ExpectationCheckResult<EX, QX> resultOfCheckingAll(List<FindingExpectation<EX,QX, C>> expectations) {
for (FindingExpectation<EX, QX, C> defaultExpectation : expectations) {
ExpectationCheckResult<EX, QX> resultOfCheckingForExpectation =
simpleCheckerForContext.resultOfChecking(defaultExpectation);
if (!resultOfCheckingForExpectation.meetsExpectation()) {
return resultOfCheckingForExpectation;
}
}
return ExpectationCheckResult.<EX,QX>satisfactoryResult(null);
}
public static <EX, QX extends Quantity<EX>, C> DefaultExpectationChecker<EX, QX, C> defaultExpectationCheckingChecker(C context){
return new DefaultExpectationChecker<EX, QX, C>(context);
}
public void removePreChecks() {
this.preChecks.clear();
}
}