/*
* Copyright (c) 2002-2017 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* 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 org.neo4j.driver.v1.tck;
import cucumber.api.DataTable;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Then;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.Value;
import org.neo4j.driver.v1.exceptions.NoSuchRecordException;
import org.neo4j.driver.v1.summary.ResultSummary;
import org.neo4j.driver.v1.tck.tck.util.ResultParser;
import org.neo4j.driver.v1.tck.tck.util.runners.CypherStatementRunner;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.neo4j.driver.v1.Values.ofValue;
import static org.neo4j.driver.v1.tck.Environment.runners;
import static org.neo4j.driver.v1.tck.tck.util.ResultParser.parseGiven;
import static org.neo4j.driver.v1.tck.tck.util.ResultParser.parseStringValue;
public class DriverStatementResultAPISteps
{
private void compareSingleRecord( Record record, List<String> keys, List<String> values )
{
assertThat( record.size(), equalTo( keys.size() ) );
assertThat( ResultParser.parseExpected( values, keys ),
equalTo( parseGiven( record.asMap( ofValue() ) ) ) );
}
@Then( "^using `Single` on `Statement Result` gives a `Record` containing:$" )
public void usingSingleOnStatementReslutGivesARecordContaining( DataTable table ) throws Throwable
{
List<String> keys = table.diffableRows().get( 0 ).convertedRow;
List<String> values = table.diffableRows().get( 1 ).convertedRow;
for ( CypherStatementRunner runner : runners )
{
compareSingleRecord( runner.result().single(), keys, values );
}
}
@Then( "^using `Single` on `Statement Result` throws exception:$" )
public void usingSingleOnStatmentReslutThrowsException( DataTable table ) throws Throwable
{
for ( CypherStatementRunner runner : runners )
{
Record single = null;
boolean success = true;
try
{
single = runner.result().single();
}
catch ( NoSuchRecordException e )
{
assertThat( e.getMessage(), startsWith( table.diffableRows().get( 1 ).convertedRow.get( 0 ) ) );
success = false;
}
if ( success )
{
throw new Exception( "Excpected exception to be thrown but was not! Got: " + single );
}
}
}
@Then( "^using `Peek` on `Statement Result` fails$" )
public void usingPeekOnStatmentReslutGivesNull() throws Throwable
{
for ( CypherStatementRunner runner : runners )
{
try
{
runner.result().peek();
throw new Exception( "Expected NoSuchErrorException but did not get one." );
}
catch ( NoSuchRecordException ignore )
{
}
}
}
@Then( "^using `Peek` on `Statement Result` gives a `Record` containing:$" )
public void usingPeekOnStatmentReslutGivesARecord( DataTable table ) throws Throwable
{
List<String> keys = table.diffableRows().get( 0 ).convertedRow;
List<String> values = table.diffableRows().get( 1 ).convertedRow;
for ( CypherStatementRunner runner : runners )
{
compareSingleRecord( runner.result().peek(), keys, values );
}
}
@And( "^using `Next` on `Statement Result` gives a `Record` containing:$" )
public void usingNextOnStatementResultGivesARecordContaining( DataTable table ) throws Throwable
{
List<String> keys = table.diffableRows().get( 0 ).convertedRow;
List<String> values = table.diffableRows().get( 1 ).convertedRow;
for ( CypherStatementRunner runner : runners )
{
compareSingleRecord( runner.result().next(), keys, values );
}
}
@And( "^using `Next` on `Statement Result` fails$" )
public void usingNextOnStatementResultGivesNull() throws Throwable
{
for ( CypherStatementRunner runner : runners )
{
try
{
runner.result().next();
throw new Exception( "Expected NoSuchErrorException but did not get one." );
}
catch ( NoSuchRecordException ignore )
{
}
}
}
@Then( "^using `Keys` on `Statement Result` gives:$" )
public void usingKeysOnStatementResultGives( List<String> data ) throws Throwable
{
HashSet<String> expected = new HashSet<>( data );
expected.remove( data.get( 0 ) );
for ( CypherStatementRunner runner : runners )
{
HashSet<String> keys = new HashSet<>( runner.result().keys() );
assertThat( keys, equalTo( expected ) );
}
}
@And( "^using `Next` on `Statement Result` gives a `Record`$" )
public void usingNextOnStatementResultGivesARecord() throws Throwable
{
for ( CypherStatementRunner runner : runners )
{
Record single = runner.result().next();
assertThat( single, instanceOf( Record.class ) );
}
}
@Then( "^it is not possible to go back$" )
public void itIsNotPossibleToGoBack() throws Throwable
{
//Move along
}
@And( "^using `List` on `Statement Result` gives a list of size (\\d+), the previous records are lost$" )
public void usingListOnStatementResultGivesAListOfSizeThePreviousRecordsAreLost( int size ) throws Throwable
{
for ( CypherStatementRunner runner : runners )
{
assertThat( runner.result().list().size(), equalTo( size ) );
}
}
@Then( "^iterating through the `Statement Result` should follow the native code pattern$" )
public void iteratingThroughTheStatementResultShouldFollowTheNativeCodePattern() throws Throwable
{
for ( CypherStatementRunner runner : runners )
{
while ( runner.result().hasNext() )
{
runner.result().next();
}
}
}
@Then( "^using `List` on `Statement Result` gives:$" )
public void usingListOnStatementResultGives( DataTable table ) throws Throwable
{
List<String> keys = table.topCells();
List<List<String>> expected = new ArrayList<>();
for ( int i = 1; i < table.diffableRows().size(); i++ )
{
expected.add( table.diffableRows().get( i ).convertedRow );
}
for ( CypherStatementRunner runner : runners )
{
while ( runner.result().hasNext() )
{
List<Record> list = runner.result().list();
while ( !list.isEmpty() )
{
int size = list.size();
for ( List<String> expectedRecord : expected )
{
try
{
compareSingleRecord( list.get( 0 ), keys, expectedRecord );
list.remove( 0 );
break;
}
catch ( AssertionError ignore ) {}
}
if ( size == list.size() )
{
throw new Exception( "Actual does not match expected." );
}
}
}
}
}
@Then( "^using `Keys` on the single record gives:$" )
public void usingKeysOnTheSingleRecordGives( List<String> data ) throws Throwable
{
HashSet<String> expected = new HashSet<>( data );
expected.remove( data.get( 0 ) );
for ( CypherStatementRunner runner : runners )
{
HashSet<String> keys = new HashSet<>( runner.result().single().keys() );
assertThat( keys, equalTo( expected ) );
}
}
@Then( "^using `Values` on the single record gives:$" )
public void usingValuesOnTheSingleRecordGives( List<String> data ) throws Throwable
{
for ( CypherStatementRunner runner : runners )
{
List<Value> givens = runner.result().single().values();
for ( int i = 1; i < data.size(); i++ )
{
Value given = parseGiven( givens.get( i - 1 ) );
Value expected = parseStringValue( data.get( i ) );
assertThat( given, equalTo( expected ) );
}
}
}
@Then( "^using `Get` with index (\\d+) on the single record gives:$" )
public void usingGetWithIndexOnTheSingleRecordGives( int index, List<String> data ) throws Throwable
{
Value expected = parseStringValue( data.get( 1 ) );
for ( CypherStatementRunner runner : runners )
{
Value given = parseGiven( runner.result().single().get( index ) );
assertThat( given, equalTo( expected ) );
}
}
@Then( "^using `Get` with key `(.*)` on the single record gives:$" )
public void usingGetWithKeyNOnTheSingleRecordGives( String key, List<String> data ) throws Throwable
{
Value expected = parseStringValue( data.get( 1 ) );
for ( CypherStatementRunner runner : runners )
{
Value given = parseGiven( runner.result().single().get( key ) );
assertThat( given, equalTo( expected ) );
}
}
@Then( "^using `Consume` on `StatementResult` gives `ResultSummary`$" )
public void usingConsumeOnStatementResultGivesResultSummary() throws Throwable
{
for ( CypherStatementRunner runner : runners )
{
assertThat( runner.result().consume(), instanceOf( ResultSummary.class ) );
}
}
@Then( "^using `Consume` on `StatementResult` multiple times gives the same `ResultSummary` each time$" )
public void usingConsumeOnStatementResultMultipleTimesGivesTheSameResultSummaryEachTime() throws Throwable
{
for ( CypherStatementRunner runner : runners )
{
ResultSummary summary = runner.result().consume();
assertThat( summary, instanceOf( ResultSummary.class ) );
assertThat( summary.counters().nodesCreated(),
equalTo( runner.result().consume().counters().nodesCreated() ) );
}
}
}