/******************************************************************************* * 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.asString; import static jhc.redsniff.core.FindingExpectations.*; import java.util.Collection; import jhc.redsniff.core.MFinder; import jhc.redsniff.core.SFinder; import jhc.redsniff.internal.core.CollectionOf; import jhc.redsniff.internal.core.Quantity; import org.hamcrest.Description; import org.hamcrest.SelfDescribing; //C1 is inner context //E1 is inner element - irrelevant //C0 is outer context -what we need parentContext to be and what we need the context finder to find from //E0 is what the context finder finds - it must extend C1 public class WithinEachContextChecker<C1, E0 extends C1, C0> extends AlwaysFindsMultipleElementsChecker<C1> implements SelfDescribing { private MFinder<E0, C0> contextFinder; private CollectionOf<C0> parentContexts; private SelfDescribing parentContextDescription; private String eachString; public WithinEachContextChecker(CollectionOf<C0> parentContexts, MFinder<E0, C0> contextFinder, SelfDescribing parentContextDescription, String eachString) { super(null); this.parentContexts = parentContexts; this.contextFinder = contextFinder; this.parentContextDescription = parentContextDescription; this.eachString = eachString; } @SuppressWarnings("unchecked") @Override public <I1, Q1 extends Quantity<I1>> CollectionOf<I1> quantityFoundBy(FindingExpectation<I1, Q1, C1> expectation) { CollectionOf<I1> allFindings = CollectionOf.fresh(); for(C1 context:contextsToSearch(expectingToSearchWithinTo(asString(expectation)))){ Quantity<I1> findings = checkerFor(context) .quantityFoundBy(contextPrinting(this,expectation)); if(findings instanceof CollectionOf) allFindings.addAll((Collection<I1>)findings.get()); else allFindings.add((I1)findings.get()); } return allFindings; } @Override public <I1, Q1 extends Quantity<I1>> boolean isSatisfied(FindingExpectation<I1, Q1, C1> expectation) { boolean isMet = true; for(C1 context : contextsToSearch(expectingToSearchWithinTo(asString(expectation)))) isMet &= checkerFor(context).isSatisfied(contextPrinting(this, expectation)); return isMet; } @Override public <I1, Q1 extends Quantity<I1>> void assertThe(FindingExpectation<I1, Q1, C1> expectation) { for(C1 context : contextsToSearch(expectingToSearchWithinTo(asString(expectation)))) checkerFor(context).assertThe(contextPrinting(this,expectation)); } @Override public <C2, E1 extends C2> WithinEachContextChecker<C2, E1, C1> inEachContextFoundBy(MFinder<E1, C1> innerContextFinder) { CollectionOf<C1> innerContexts = contextsToSearch(expectingToSearchWithinTo(asString(expectationOfSome(innerContextFinder)))); return new WithinEachContextChecker<C2, E1, C1>(innerContexts, innerContextFinder, this, eachString); } @Override public <C2, E1 extends C2> WithinSingleContextChecker<C2, E1, C1> inSingleContextFoundBy(SFinder<E1,C1> innerContextFinder){ // SFinder<E1, C1> innerContextFinder) { // CollectionOf<C1> innerContexts = contextsToSearch(expectingToSearchWithinTo(asString(expectationOfSome(innerContextFinder)))); // return new WithinEachContextChecker<C2, E1, C1>(innerContexts, innerContextFinder, this, eachString); throw new UnsupportedOperationException("inSingleContext from inEach"); } public CollectionOf<C1> contextsToSearch( FindingExpectation<E0, CollectionOf<E0>, C0> expectingToSearchWithinTo) { CollectionOf<C1> allContexts=CollectionOf.fresh(); for(C0 parentContext: parentContexts){ allContexts.addAll(checkerFor(parentContext).thatWhichIsFoundBy(expectingToSearchWithinTo)); } return allContexts; } public <I1> FindingExpectation<E0, CollectionOf<E0>, C0> expectingToSearchWithinTo(String purposeOfSearching){ return expectationWithPurpose(contextFinder, "search within to find " + purposeOfSearching); } @Override public void describeTo(Description description) { if (parentContextDescription != null) description.appendDescriptionOf(parentContextDescription); description.appendText("\n, in ").appendText(eachString + " ").appendDescriptionOf(contextFinder); } }