/** * Copyright 2011-2017 Asakusa Framework Team. * * 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 com.asakusafw.testdriver; import java.io.File; import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.function.UnaryOperator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.asakusafw.testdriver.core.DataModelDefinition; import com.asakusafw.testdriver.core.DataModelSinkFactory; import com.asakusafw.testdriver.core.DataModelSource; import com.asakusafw.testdriver.core.DataModelSourceFactory; import com.asakusafw.testdriver.core.DataModelSourceFilter; import com.asakusafw.testdriver.core.DifferenceSinkFactory; import com.asakusafw.testdriver.core.ModelTester; import com.asakusafw.testdriver.core.ModelTransformer; import com.asakusafw.testdriver.core.ModelVerifier; import com.asakusafw.testdriver.core.TestDataToolProvider; import com.asakusafw.testdriver.core.TestRule; import com.asakusafw.testdriver.core.VerifierFactory; import com.asakusafw.testdriver.core.VerifyRuleFactory; /** * An abstract super class of test driver outputs. * @since 0.2.0 * @version 0.7.0 * @param <T> the data model type */ public class DriverOutputBase<T> extends DriverInputBase<T> { private static final Logger LOG = LoggerFactory.getLogger(DriverOutputBase.class); private VerifierFactory verifier; private DataModelSinkFactory resultSink; private DifferenceSinkFactory differenceSink; private UnaryOperator<DataModelSource> resultFilter; /** * Creates a new instance. * @param callerClass the current context class * @param testTools the test data tools * @param name the original input name * @param modelType the data model type * @since 0.6.0 */ public DriverOutputBase(Class<?> callerClass, TestDataToolProvider testTools, String name, Class<T> modelType) { super(callerClass, testTools, name, modelType); } /** * Returns the verifier. * @return the verifier, or {@code null} if not defined * @since 0.2.3 */ public VerifierFactory getVerifier() { if (verifier == null) { return null; } else if (resultFilter == null) { return verifier; } else { return toVerifierFactory(verifier, resultFilter); } } /** * Sets the verify rule for this output. * @param verifier the verifier to set, or {@code null} to clear verifier * @since 0.2.3 */ protected final void setVerifier(VerifierFactory verifier) { if (LOG.isDebugEnabled()) { LOG.debug("Verifier: name={}, model={}, verifier={}", new Object[] { //$NON-NLS-1$ getName(), getModelType().getName(), verifier, }); } this.verifier = verifier; } /** * Returns the result data sink for this output. * @return the result data sink, or {@code null} if not defined * @since 0.2.3 */ public DataModelSinkFactory getResultSink() { return resultSink; } /** * Sets the result data sink for this output. * The specified object will save the actual result of this. * @param resultSink the result data sink to set, or {@code null} to clear the sink * @since 0.2.3 */ protected final void setResultSink(DataModelSinkFactory resultSink) { if (LOG.isDebugEnabled()) { LOG.debug("ResultSink: name={}, model={}, sink={}", new Object[] { //$NON-NLS-1$ getName(), getModelType().getName(), resultSink, }); } this.resultSink = resultSink; } /** * Returns the difference information sink for this output. * @return the difference information sink, or {@code null} if not defined * @since 0.2.3 */ public DifferenceSinkFactory getDifferenceSink() { return differenceSink; } /** * Sets the difference information sink for this output. * The specified object will save the difference from expected result of this. * @param differenceSink the difference sink to set, {@code null} to clear the sink * @since 0.2.3 */ protected final void setDifferenceSink(DifferenceSinkFactory differenceSink) { if (LOG.isDebugEnabled()) { LOG.debug("DifferenceSink: name={}, model={}, sink={}", new Object[] { //$NON-NLS-1$ getName(), getModelType().getName(), differenceSink, }); } this.differenceSink = differenceSink; } /** * Sets the data model source filter for actual results of this output. * @param filter the source filter * @since 0.7.0 */ protected final void setResultFilter(UnaryOperator<DataModelSource> filter) { this.resultFilter = filter; } /** * Converts an output path to {@link DataModelSinkFactory} to write to the path. * @param path the output path * @return the target sink factory * @since 0.6.0 */ protected final DataModelSinkFactory toDataModelSinkFactory(String path) { return getTestTools().getDataModelSinkFactory(toOutputUri(path)); } /** * Converts an output path to {@link DataModelSinkFactory} to write to the path. * @param path the output path * @return the target sink factory * @since 0.6.0 */ protected final DataModelSinkFactory toDataModelSinkFactory(File path) { return getTestTools().getDataModelSinkFactory(path.toURI()); } /** * Converts an output path to {@link DifferenceSinkFactory} to write to the path. * @param path the output path * @return the target sink factory * @since 0.6.0 */ protected final DifferenceSinkFactory toDifferenceSinkFactory(String path) { return getTestTools().getDifferenceSinkFactory(toOutputUri(path)); } /** * Converts an output path to {@link DifferenceSinkFactory} to write to the path. * @param path the output path * @return the target sink factory * @since 0.6.0 */ protected final DifferenceSinkFactory toDifferenceSinkFactory(File path) { return getTestTools().getDifferenceSinkFactory(path.toURI()); } /** * Converts an model transformer into {@link DataModelSourceFilter}. * @param transformer the data model transformer * @return the filter which transforms each data model objects using the transformer * @since 0.7.0 */ protected final DataModelSourceFilter toDataModelSourceFilter(ModelTransformer<? super T> transformer) { DataModelDefinition<T> definition = getDataModelDefinition(); return toDataModelSourceFilter(definition, transformer); } /** * Converts {@link ModelVerifier} into {@link VerifyRuleFactory}. * @param rulePath the path which represents the verification rule description * @param extraRules the extra verification rules * @return the equivalent {@link VerifyRuleFactory} * @since 0.6.0 */ protected final VerifyRuleFactory toVerifyRuleFactory( String rulePath, List<? extends ModelTester<? super T>> extraRules) { try { TestDataToolProvider tools = getTestTools(); List<TestRule> fragments = new ArrayList<>(); for (ModelTester<? super T> tester : extraRules) { fragments.add(tools.toVerifyRuleFragment(getDataModelDefinition(), tester)); } return tools.getVerifyRuleFactory(toUri(rulePath), fragments); } catch (URISyntaxException e) { throw new IllegalStateException(MessageFormat.format( "Invalid rule path: {0}", //$NON-NLS-1$ rulePath), e); } } /** * Converts {@link ModelVerifier} into {@link VerifyRuleFactory}. * @param modelVerifier the original verifier * @return the equivalent {@link VerifyRuleFactory} * @since 0.6.0 */ protected final VerifyRuleFactory toVerifyRuleFactory(ModelVerifier<? super T> modelVerifier) { return getTestTools().toVerifyRuleFactory(getDataModelDefinition(), modelVerifier); } /** * Converts a pair of expected data set factory and verify rule factory into {@link VerifyRuleFactory}. * @param expectedFactory the expected data set factory * @param ruleFactory the verification rule factory * @return the {@link VerifierFactory} which provides a verifier using the expected data set and verification rule * @since 0.6.0 */ protected final VerifierFactory toVerifierFactory( DataModelSourceFactory expectedFactory, VerifyRuleFactory ruleFactory) { return getTestTools().toVerifierFactory(expectedFactory, ruleFactory); } }