package com.tinkerpop.gremlin.structure;

import com.tinkerpop.gremlin.AbstractGremlinTest;
import com.tinkerpop.gremlin.structure.util.GraphFactory;
import org.apache.commons.configuration.Configuration;
import org.junit.Test;

import java.lang.reflect.Modifier;
import java.util.Arrays;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
 * Tests that support the creation of {@link com.tinkerpop.gremlin.structure.Graph} instances which occurs via
 * {@link com.tinkerpop.gremlin.structure.util.GraphFactory}.
 *
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
public class GraphConstructionTest extends AbstractGremlinTest {
    /**
     * All Gremlin Structure implementations should be constructable through
     * {@link com.tinkerpop.gremlin.structure.util.GraphFactory}.
     */
    @Test
    public void shouldOpenGraphThroughGraphFactoryViaApacheConfig() throws Exception {
        final Graph expectedGraph = g;
        final Configuration c = graphProvider.newGraphConfiguration("temp", this.getClass(), name.getMethodName());
        final Graph createdGraph = GraphFactory.open(c);

        assertNotNull(createdGraph);
        assertEquals(expectedGraph.getClass(), createdGraph.getClass());

        graphProvider.clear(g, c);
    }

    /**
     * Gremlin Structure  implementations should have private constructor as all graphs.  They should be only
     * instantiated through the {@link com.tinkerpop.gremlin.structure.util.GraphFactory} or the static
     * {@link com.tinkerpop.gremlin.structure.util.GraphFactory#open(org.apache.commons.configuration.Configuration)}
     * method on the Graph implementation itself.
     */
    @Test
    public void shouldHavePrivateConstructor() {
        assertTrue(Arrays.asList(g.getClass().getConstructors()).stream().allMatch(c -> {
            final int modifier = c.getModifiers();
            return Modifier.isPrivate(modifier) || Modifier.isPrivate(modifier);
        }));
    }

    /**
     * Graphs should be empty on creation.
     */
    @Test
    public void shouldConstructAnEmptyGraph() {
        assertVertexEdgeCounts(0, 0).accept(g);
    }
}

@@ -143,16 +143,65 @@
 actory;%0A
+import com.tinkerpop.gremlin.util.StreamFactory;%0A
 import o
@@ -330,16 +330,143 @@
 .Arrays;
+%0Aimport java.util.Iterator;%0Aimport java.util.concurrent.atomic.AtomicBoolean;%0Aimport java.util.concurrent.atomic.AtomicInteger;
 %0A%0Aimport
@@ -1270,16 +1270,17 @@
 on(%22temp
+1
 %22, this.
@@ -2394,11 +2394,855 @@
 );%0A    %7D
+%0A%0A    /**%0A     * A %7B@link Graph%7D%0A     */%0A    @Test%0A    public void shouldMaintainOriginalConfigurationObjectGivenToFactory() %7B%0A        final Configuration originalConfig = graphProvider.newGraphConfiguration(%22temp2%22, this.getClass(), name.getMethodName());%0A        final Graph createdGraph = GraphFactory.open(originalConfig);%0A%0A        final Configuration configInGraph = createdGraph.configuration();%0A        final AtomicInteger keyCount = new AtomicInteger(0);%0A        originalConfig.getKeys().forEachRemaining(k -%3E %7B%0A            assertTrue(configInGraph.containsKey(k));%0A            keyCount.incrementAndGet();%0A        %7D);%0A%0A        // need some keys in the originalConfig for this test to be meaningful%0A        assertTrue(keyCount.get() %3E 0);%0A        assertEquals(keyCount.get(), StreamFactory.stream(configInGraph.getKeys()).count());%0A    %7D
 %0A%7D%0A

Add test to enforce Graph.configuration() operations #284