Skip to content

Commit

Permalink
Use matchers for containers
Browse files Browse the repository at this point in the history
  • Loading branch information
Mats-SX committed Mar 3, 2016
1 parent de98e59 commit 9e9c496
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 18 deletions.
Expand Up @@ -24,6 +24,8 @@
import cypher.feature.parser.matchers.BooleanMatcher;
import cypher.feature.parser.matchers.FloatMatcher;
import cypher.feature.parser.matchers.IntegerMatcher;
import cypher.feature.parser.matchers.ListMatcher;
import cypher.feature.parser.matchers.MapMatcher;
import cypher.feature.parser.matchers.NullMatcher;
import cypher.feature.parser.matchers.StringMatcher;
import cypher.feature.parser.matchers.ValueMatcher;
Expand Down Expand Up @@ -118,14 +120,14 @@ public void enterListElement( FeatureResultsParser.ListElementContext ctx )
@Override
public void exitList( FeatureResultsParser.ListContext ctx )
{
// Using a Deque here in order to be able to prepend
Deque<Object> temp = new LinkedList<>();
// Using a LinkedList here in order to be able to prepend
LinkedList<ValueMatcher> temp = new LinkedList<>();
int counter = listCounters.pop();
for ( int i = 0; i < counter; ++i )
{
temp.addFirst( oldworkload.pop() );
temp.addFirst( workload.pop() );
}
oldworkload.push( temp );
workload.push( new ListMatcher( temp ) );
}

@Override
Expand All @@ -144,14 +146,14 @@ public void enterKeyValuePair( FeatureResultsParser.KeyValuePairContext ctx )
public void exitPropertyMap( FeatureResultsParser.PropertyMapContext ctx )
{
int counter = mapCounters.pop();
Map<String,Object> map = new HashMap<>();
Map<String,ValueMatcher> map = new HashMap<>();
for ( int i = 0; i < counter; ++i )
{
Object value = oldworkload.pop();
ValueMatcher value = workload.pop();
String key = oldworkload.pop().toString();
map.put( key, value );
}
oldworkload.push( map );
workload.push( new MapMatcher(map) );
}

@Override
Expand Down
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cypher.feature.parser.matchers;

import java.util.List;

public class ListMatcher implements ValueMatcher
{
private final List<ValueMatcher> list;

public ListMatcher( List<ValueMatcher> list )
{
this.list = list;
}

@Override
public boolean matches( Object value )
{
if ( value instanceof List )
{
List realList = (List) value;
boolean match = realList.size() == list.size();
for ( int i = 0; i < list.size(); ++i )
{
match &= list.get( i ).matches( realList.get( i ) );
}
return match;
}
return false;
}
}
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cypher.feature.parser.matchers;

import java.util.Map;
import java.util.Set;

public class MapMatcher implements ValueMatcher
{
private final Map<String,ValueMatcher> map;

public MapMatcher( Map<String,ValueMatcher> map )
{
this.map = map;
}

@Override
public boolean matches( Object value )
{
if ( value instanceof Map )
{
Map<String,Object> realMap = (Map<String,Object>) value;
Set<String> expectedKeys = map.keySet();
Set<String> actualKeys = realMap.keySet();
boolean match = expectedKeys.equals( actualKeys );

if ( match )
{
for ( String key : expectedKeys )
{
match &= map.get( key ).matches( realMap.get( key ) );
}
return match;
}
}
return false;
}
}
Expand Up @@ -30,6 +30,8 @@ import org.neo4j.graphdb._
import org.scalatest.matchers.{MatchResult, Matcher}
import org.scalatest.{FunSuite, Matchers}

import scala.collection.JavaConverters._

class expectedResultsParserTest extends FunSuite with Matchers {

test("should parse null") {
Expand Down Expand Up @@ -83,26 +85,33 @@ class expectedResultsParserTest extends FunSuite with Matchers {
}

test("should parse list") {
valueParse("[]") should equal(emptyList())
valueParse("['\"\n\r\f\t']") should equal(asList("\"\n\r\f\t"))
valueParse("[0, 1.0e-10, '$', true]") should equal(asList(0L, 1e-10, "$", TRUE))
valueParse("['', ',', ' ', ', ', 'end']") should equal(asList("", ",", " ", ", ", "end"))
parse("[]") should accept(List.empty.asJava)
parse("['\"\n\r\f\t']") should accept(List("\"\n\r\f\t").asJava)
parse("[0, 1.0e-10, '$', true]") should accept(List(0L, 1e-10, "$", TRUE).asJava)
parse("['', ',', ' ', ', ', 'end']") should accept(List("", ",", " ", ", ", "end").asJava)
}

test("should parse nested list") {
valueParse("[[]]") should equal(asList(emptyList()))
valueParse("[[[0]], [0], 0]") should equal(asList(asList(asList(0L)), asList(0L), 0L))
parse("[[]]") should accept(List(List.empty.asJava).asJava)
parse("[[[0]], [0], 0]") should accept(List(List(List(0L).asJava).asJava, List(0L).asJava, 0L).asJava)
}

test("should parse maps") {
valueParse("{}") should equal(emptyMap())
valueParse("{k0:'\n\r\f\t'}") should equal(asMap(Map("k0" -> "\n\r\f\t")))
valueParse("{k0:0, k1:1.0e-10, k2:null, k3:true}") should equal(
asMap(Map("k0" -> Long.valueOf(0), "k1" -> lang.Double.valueOf(1e-10), "k2" -> null, "k3" -> TRUE)))
parse("{}") should accept(Map.empty.asJava)
parse("{k0:'\n\r\f\t'}") should accept(Map("k0" -> "\n\r\f\t").asJava)

parse("{k0:0, k1:1.0e-10, k2:null, k3:true}") should accept(
Map("k0" -> Long.valueOf(0), "k1" -> lang.Double.valueOf(1e-10), "k2" -> null, "k3" -> TRUE).asJava)
}

test("should parse nested maps") {
parse("{key: {key: 'value', key2: {}}, key2: []}") should accept(
Map("key" -> Map("key" -> "value", "key2" -> Map.empty.asJava).asJava, "key2" -> List.empty.asJava).asJava)
}

test("should allow whitespace between key and value") {
valueParse("{key:'value'}") should equal(valueParse("{key: 'value'}"))
parse("{key:'value'}") should accept(Map("key" -> "value").asJava)
parse("{key: 'value'}") should accept(Map("key" -> "value").asJava)
}

test("should parse nodes with labels") {
Expand Down

0 comments on commit 9e9c496

Please sign in to comment.