blob: 05b1f6a17dbaf2ab7b841ad496b39d601f9895a9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.tinkerpop.gremlin.process.traversal;
import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalInterruptedException;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsCollectionContaining.hasItems;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.fail;
/**
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public class TraversalTest {
@Test
public void shouldTryNext() {
final MockTraversal<Integer> t = new MockTraversal<>(1, 2, 3);
final Optional<Integer> optFirst = t.tryNext();
assertEquals(1, optFirst.get().intValue());
final Optional<Integer> optSecond = t.tryNext();
assertEquals(2, optSecond.get().intValue());
final Optional<Integer> optThird = t.tryNext();
assertEquals(3, optThird.get().intValue());
IntStream.range(0, 100).forEach(i -> {
assertThat(t.tryNext().isPresent(), is(false));
});
}
@Test
public void shouldGetTwoAtATime() {
final MockTraversal<Integer> t = new MockTraversal<>(1, 2, 3, 4, 5, 6, 7);
final List<Integer> batchOne = t.next(2);
assertEquals(2, batchOne.size());
assertThat(batchOne, hasItems(1 ,2));
final List<Integer> batchTwo = t.next(2);
assertEquals(2, batchTwo.size());
assertThat(batchTwo, hasItems(3 ,4));
final List<Integer> batchThree = t.next(2);
assertEquals(2, batchThree.size());
assertThat(batchThree, hasItems(5, 6));
final List<Integer> batchFour = t.next(2);
assertEquals(1, batchFour.size());
assertThat(batchFour, hasItems(7));
final List<Integer> batchFive = t.next(2);
assertEquals(0, batchFive.size());
}
@Test
public void shouldFillList() {
final MockTraversal<Integer> t = new MockTraversal<>(1, 2, 3, 4, 5, 6, 7);
final List<Integer> listToFill = new ArrayList<>();
final List<Integer> batch = t.fill(listToFill);
assertEquals(7, batch.size());
assertThat(batch, hasItems(1 ,2, 3, 4, 5, 6, 7));
assertThat(t.hasNext(), is(false));
assertSame(listToFill, batch);
}
@Test
public void shouldStream() {
final MockTraversal<Integer> t = new MockTraversal<>(1, 2, 3, 4, 5, 6, 7);
final List<Integer> batch = t.toStream().collect(Collectors.toList());
assertEquals(7, batch.size());
assertThat(batch, hasItems(1 ,2, 3, 4, 5, 6, 7));
assertThat(t.hasNext(), is(false));
}
@Test
public void shouldIterate() {
final MockTraversal<Integer> t = new MockTraversal<>(1, 2, 3, 4, 5, 6, 7);
assertThat(t.hasNext(), is(true));
t.iterate();
assertThat(t.hasNext(), is(false));
}
@Test
public void shouldCloseWithoutACloseableStep() throws Exception {
final MockTraversal<Integer> t = new MockTraversal<>(1, 2, 3, 4, 5, 6, 7);
assertThat(t.hasNext(), is(true));
t.close();
assertThat(t.isClosed(), is(false));
}
@Test
public void shouldCloseWithCloseableStep() throws Exception {
final MockTraversal<Integer> t = new MockTraversal<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7).iterator(), true);
assertThat(t.hasNext(), is(true));
t.close();
assertThat(t.isClosed(), is(true));
}
@Test
public void shouldOnlyAllowAnonymousChildren() {
final GraphTraversalSource g = traversal().withGraph(EmptyGraph.instance());
g.V(1).addE("self").to(__.V(1));
try {
g.V(1).addE("self").to(g.V(1));
fail("Should not allow child traversals spawned from 'g'");
} catch (IllegalStateException ignored) {}
}
private static class MockCloseStep<E> extends MockStep<E> implements AutoCloseable {
private boolean closed = false;
public MockCloseStep(final Iterator<E> itty) {
super(itty);
}
boolean isClosed() {
return closed;
}
@Override
public void close() throws Exception {
closed = true;
}
}
private static class MockStep<E> implements Step<E,E> {
private final Iterator<E> itty;
MockStep(final Iterator<E> itty) {
this.itty = itty;
}
@Override
public void addStarts(final Iterator starts) {
}
@Override
public void addStart(final Traverser.Admin start) {
}
@Override
public boolean hasStarts() {
return false;
}
@Override
public void setPreviousStep(final Step step) {
}
@Override
public Step getPreviousStep() {
return null;
}
@Override
public void setNextStep(final Step step) {
}
@Override
public Step getNextStep() {
return null;
}
@Override
public Traversal.Admin getTraversal() {
return null;
}
@Override
public void setTraversal(final Traversal.Admin traversal) {
}
@Override
public void reset() {
}
@Override
public Step clone() {
return null;
}
@Override
public Set<String> getLabels() {
return null;
}
@Override
public void addLabel(final String label) {
}
@Override
public void removeLabel(final String label) {
}
@Override
public void setId(final String id) {
}
@Override
public String getId() {
return null;
}
@Override
public boolean hasNext() {
return itty.hasNext();
}
@Override
public Traverser.Admin<E> next() {
return new DefaultRemoteTraverser<>(itty.next(), 1L);
}
}
private static class MockTraversal<T> implements Traversal.Admin<T,T> {
private Iterator<T> itty;
private Step mockEndStep;
private List<Step> steps;
MockTraversal(final T... objects) {
this(Arrays.asList(objects));
}
MockTraversal(final List<T> list) {
this(list.iterator(), false);
}
MockTraversal(final Iterator<T> itty, final boolean asCloseable) {
this.itty = itty;
mockEndStep = asCloseable ? new MockCloseStep<>(itty) : new MockStep<>(itty);
steps = Collections.singletonList(mockEndStep);
}
boolean isClosed() {
return mockEndStep instanceof MockCloseStep && ((MockCloseStep) mockEndStep).isClosed();
}
@Override
public Bytecode getBytecode() {
return new Bytecode();
}
@Override
public List<Step> getSteps() {
return steps;
}
@Override
public <S2, E2> Admin<S2, E2> addStep(final int index, final Step<?, ?> step) throws IllegalStateException {
return null;
}
@Override
public <S2, E2> Admin<S2, E2> removeStep(final int index) throws IllegalStateException {
return null;
}
@Override
public void applyStrategies() throws IllegalStateException {
}
@Override
public TraverserGenerator getTraverserGenerator() {
return null;
}
@Override
public Set<TraverserRequirement> getTraverserRequirements() {
return null;
}
@Override
public void setSideEffects(final TraversalSideEffects sideEffects) {
}
@Override
public TraversalSideEffects getSideEffects() {
return null;
}
@Override
public void setStrategies(final TraversalStrategies strategies) {
}
@Override
public TraversalStrategies getStrategies() {
return null;
}
@Override
public void setParent(final TraversalParent step) {
}
@Override
public TraversalParent getParent() {
return null;
}
@Override
public Admin<T, T> clone() {
return null;
}
@Override
public boolean isLocked() {
return false;
}
@Override
public Optional<Graph> getGraph() {
return null;
}
@Override
public void setGraph(final Graph graph) {
}
@Override
public boolean hasNext() {
return itty.hasNext();
}
@Override
public T next() {
if (Thread.interrupted()) throw new TraversalInterruptedException();
return itty.next();
}
}
}