package com.tinkerpop.blueprints;

import com.tinkerpop.blueprints.computer.GraphComputer;
import org.junit.Test;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.junit.Assert.assertTrue;

/**
 * A set of tests that ensure that the {@link ExceptionConsistencyTest} covers all defined Blueprints exceptions.
 *
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
public class ExceptionCoverageTest {
    @Test
    public void shouldCoverAllExceptionsInTests() {
        final Class[] blueprintsExceptions = {
                AnnotatedList.Exceptions.class,
                Annotations.Exceptions.class,
                Edge.Exceptions.class,
                Element.Exceptions.class,
                Graph.Exceptions.class,
                GraphComputer.Exceptions.class,
                Property.Exceptions.class,
                Transaction.Exceptions.class,
                Vertex.Exceptions.class
        };

        // this is a list of exceptions that are "excused" from the coverage tests.  in most cases there should only
        // be exceptions ignored if they are "base" exception methods that are used to compose other exceptions,
        // like the first set listed (and labelled as such) below in the list assignments.
        final Set<String> ignore = new HashSet<String>() {{
            // these exceptions is not used directly...they are called by other exception methods.
            add("com.tinkerpop.blueprints.Annotations$Exceptions#annotationKeyIsReserved");
            add("com.tinkerpop.blueprints.Property$Exceptions#propertyKeyIsReserved");

            // this is a general exception to be used as needed.  it is not explicitly tested:
            add("com.tinkerpop.blueprints.Graph$Exceptions#argumentCanNotBeNull");

            // todo: need to write consistency tests for the following items still...........
            add("com.tinkerpop.blueprints.computer.GraphComputer$Exceptions#adjacentElementPropertiesCanNotBeRead");
            add("com.tinkerpop.blueprints.computer.GraphComputer$Exceptions#adjacentElementPropertiesCanNotBeWritten");
            add("com.tinkerpop.blueprints.computer.GraphComputer$Exceptions#constantComputeKeyHasAlreadyBeenSet");
            add("com.tinkerpop.blueprints.computer.GraphComputer$Exceptions#adjacentVerticesCanNotBeQueried");
            add("com.tinkerpop.blueprints.Transaction$Exceptions#transactionMustBeOpenToReadWrite");
            add("com.tinkerpop.blueprints.Transaction$Exceptions#openTransactionsOnClose");
        }};

        // implemented exceptions are the classes that potentially contains exception consistency checks.
        final Set<String> implementedExceptions = Stream.concat(Stream.of(ExceptionConsistencyTest.class.getDeclaredClasses()),
                                                                Stream.of(FeatureSupportTest.class.getDeclaredClasses()))
            .flatMap(c -> Stream.of(c.getAnnotationsByType(ExceptionCoverage.class)))
            .flatMap(ec -> Stream.of(ec.methods()).map(m -> String.format("%s#%s", ec.exceptionClass().getName(), m)))
            .collect(Collectors.<String>toSet());

        Stream.of(blueprintsExceptions).flatMap(c -> Stream.of(c.getDeclaredMethods()).map(m -> String.format("%s#%s", c.getName(), m.getName())))
                .filter(s -> !ignore.contains(s))
                .forEach(s -> {
                    System.out.println(s);
                    assertTrue(implementedExceptions.contains(s));
                });
    }
}

@@ -551,16 +551,96 @@
 ests() %7B
+%0A%0A        // these are the classes that have Exceptions that need to be checked.
 %0A       
@@ -3293,24 +3293,215 @@
 %3EtoSet());%0A%0A
+        // evaluate each of the blueprints exceptions and find the list of exception methods...assert them against%0A        // the list of implementedExceptions to make sure they are covered.%0A
         Stre

Add inline comments on exception consistency coverage.