/** * 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.core; import java.io.IOException; import java.net.URI; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.asakusafw.testdriver.rule.VerifyRuleBuilder; import com.asakusafw.vocabulary.external.ExporterDescription; /** * Inspects each test result. * @since 0.2.0 * @deprecated Use {@link TestModerator} instead */ @Deprecated public class TestResultInspector { static final Logger LOG = LoggerFactory.getLogger(TestResultInspector.class); private final DataModelAdapter adapter; private final DataModelSourceProvider sources; private final VerifyRuleProvider rules; private final ExporterRetriever<ExporterDescription> targets; private final TestContext context; /** * Creates a new instance which uses registerd services. * @param serviceClassLoader class loader to load services * @throws IllegalArgumentException if some parameters were {@code null} */ public TestResultInspector(ClassLoader serviceClassLoader) { this(new TestContext.Empty(), serviceClassLoader); } /** * Creates a new instance which uses the specified services. * @param adapter data model driver * @param sources test data provider * @param rules verification rule provider * @param retrievers test result retrievers * @throws IllegalArgumentException if some parameters were {@code null} */ public TestResultInspector( DataModelAdapter adapter, DataModelSourceProvider sources, VerifyRuleProvider rules, ExporterRetriever<ExporterDescription> retrievers) { this(new TestContext.Empty(), adapter, sources, rules, retrievers); } /** * Creates a new instance which uses registerd services. * @param context the current context * @param serviceClassLoader class loader to load services * @throws IllegalArgumentException if some parameters were {@code null} * @since 0.2.2 */ public TestResultInspector(TestContext context, ClassLoader serviceClassLoader) { if (context == null) { throw new IllegalArgumentException("context must not be null"); //$NON-NLS-1$ } if (serviceClassLoader == null) { throw new IllegalArgumentException("serviceClassLoader must not be null"); //$NON-NLS-1$ } this.context = context; this.adapter = new SpiDataModelAdapter(serviceClassLoader); this.sources = new SpiDataModelSourceProvider(serviceClassLoader); this.rules = new SpiVerifyRuleProvider(serviceClassLoader); this.targets = new SpiExporterRetriever(serviceClassLoader); } /** * Creates a new instance which uses the specified services. * @param context the current context * @param adapter data model driver * @param sources test data provider * @param rules verification rule provider * @param retrievers test result retrievers * @throws IllegalArgumentException if some parameters were {@code null} * @since 0.2.2 */ public TestResultInspector( TestContext context, DataModelAdapter adapter, DataModelSourceProvider sources, VerifyRuleProvider rules, ExporterRetriever<ExporterDescription> retrievers) { if (adapter == null) { throw new IllegalArgumentException("adapter must not be null"); //$NON-NLS-1$ } if (sources == null) { throw new IllegalArgumentException("sources must not be null"); //$NON-NLS-1$ } if (rules == null) { throw new IllegalArgumentException("rules must not be null"); //$NON-NLS-1$ } if (retrievers == null) { throw new IllegalArgumentException("retrievers must not be null"); //$NON-NLS-1$ } this.context = context; this.adapter = adapter; this.sources = sources; this.rules = rules; this.targets = retrievers; } /** * Inspects the target exporter's output using specified expected data and rule. * @param modelClass class of data model * @param description target exporter * @param verifyContext current verification context * @param expected the expected data * @param rule the verification rule between expected and actual result * @return detected invalid differences * @throws IOException if failed to inspect the result * @throws IllegalArgumentException if some parameters were {@code null} */ public List<Difference> inspect( Class<?> modelClass, ExporterDescription description, VerifyContext verifyContext, URI expected, URI rule) throws IOException { if (modelClass == null) { throw new IllegalArgumentException("modelClass must not be null"); //$NON-NLS-1$ } if (description == null) { throw new IllegalArgumentException("description must not be null"); //$NON-NLS-1$ } if (verifyContext == null) { throw new IllegalArgumentException("verifyContext must not be null"); //$NON-NLS-1$ } if (expected == null) { throw new IllegalArgumentException("expected must not be null"); //$NON-NLS-1$ } if (rule == null) { throw new IllegalArgumentException("rule must not be null"); //$NON-NLS-1$ } DataModelDefinition<?> definition = findDefinition(modelClass); VerifyRule ruleDesc = findRule(definition, verifyContext, rule); return inspect(modelClass, description, expected, ruleDesc); } /** * Creates a {@link VerifyRuleBuilder} for the target model class. * @param modelClass target model class * @return created {@link VerifyRuleBuilder} * @throws IOException if failed to create * @throws IllegalArgumentException if some parameters were {@code null} */ public VerifyRuleBuilder rule(Class<?> modelClass) throws IOException { if (modelClass == null) { throw new IllegalArgumentException("modelClass must not be null"); //$NON-NLS-1$ } DataModelDefinition<?> definition = findDefinition(modelClass); return new VerifyRuleBuilder(definition); } /** * Converts {@link ModelVerifier} into {@link VerifyRule}. * @param <T> type of model * @param modelClass class of model * @param verifier target verifier * @return converted rule * @throws IOException if failed to convert * @throws IllegalArgumentException if some parameters were {@code null} */ public <T> VerifyRule rule(Class<? extends T> modelClass, ModelVerifier<T> verifier) throws IOException { if (modelClass == null) { throw new IllegalArgumentException("modelClass must not be null"); //$NON-NLS-1$ } if (verifier == null) { throw new IllegalArgumentException("verifier must not be null"); //$NON-NLS-1$ } DataModelDefinition<? extends T> definition = findDefinition(modelClass); return new ModelVerifierDriver<>(verifier, definition); } /** * Inspects the target exporter's output using specified expected data and rule. * @param modelClass class of data model * @param description target exporter * @param expected the expected data * @param rule the verification rule between expected and actual result * @return detected invalid differences * @throws IOException if failed to inspect the result * @throws IllegalArgumentException if some parameters were {@code null} */ public List<Difference> inspect( Class<?> modelClass, ExporterDescription description, URI expected, VerifyRule rule) throws IOException { if (modelClass == null) { throw new IllegalArgumentException("modelClass must not be null"); //$NON-NLS-1$ } if (description == null) { throw new IllegalArgumentException("description must not be null"); //$NON-NLS-1$ } if (expected == null) { throw new IllegalArgumentException("expected must not be null"); //$NON-NLS-1$ } if (rule == null) { throw new IllegalArgumentException("rule must not be null"); //$NON-NLS-1$ } DataModelDefinition<?> definition = findDefinition(modelClass); DataModelSource expectedDesc = findSource(definition, expected); VerifyEngine engine = buildVerifier(definition, rule, expectedDesc); List<Difference> results = inspect(definition, description, engine); return results; } private <T> DataModelDefinition<T> findDefinition(Class<T> modelClass) throws IOException { assert modelClass != null; DataModelDefinition<T> definition = adapter.get(modelClass); if (definition == null) { throw new IOException(MessageFormat.format( Messages.getString("TestResultInspector.errorMissingDataModelDefinition"), //$NON-NLS-1$ modelClass.getName())); } return definition; } private <T> List<Difference> inspect( DataModelDefinition<T> definition, ExporterDescription description, VerifyEngine engine) throws IOException { assert definition != null; assert description != null; assert engine != null; List<Difference> results = new ArrayList<>(); try (DataModelSource target = targets.createSource(definition, description, context)) { results.addAll(engine.inspectInput(target)); } results.addAll(engine.inspectRest()); return results; } private VerifyEngine buildVerifier( DataModelDefinition<?> definition, VerifyRule rule, DataModelSource expected) throws IOException { assert definition != null; assert rule != null; VerifyEngine engine = new VerifyEngine(rule); engine.addExpected(expected); return engine; } private DataModelSource findSource(DataModelDefinition<?> definition, URI uri) throws IOException { assert definition != null; assert uri != null; DataModelSource expected = sources.open(definition, uri, context); if (expected == null) { throw new IOException(MessageFormat.format( Messages.getString("TestResultInspector.errorMissingDataModelSource"), //$NON-NLS-1$ uri)); } return expected; } private VerifyRule findRule( DataModelDefinition<?> definition, VerifyContext verifyContext, URI ruleUri) throws IOException { assert definition != null; assert verifyContext != null; assert ruleUri != null; VerifyRule rule = rules.get(definition, verifyContext, ruleUri); if (rule == null) { throw new IOException(MessageFormat.format( Messages.getString("TestResultInspector.errorMissingVerifyRule"), //$NON-NLS-1$ ruleUri)); } return rule; } }