Newer
Older
/*
This program has been developed by students from the bachelor Computer Science at Utrecht University within the Software Project course.
© Copyright Utrecht University (Department of Information and Computing Sciences)
*/
"errors"
Geurtjens,D. (Douwe Geurtjens)
committed
"regexp"
"git.science.uu.nl/graphpolaris/query-conversion/entity"
"github.com/stretchr/testify/assert"
)
/*
Tests an empty query
t: *testing.T, makes go recognise this as a test
*/
func TestEmptyQueryConversion(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [],
"relations": []
},
"entities": [],
"relations": [],
"groupBys": [],
"filters": [],
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON
json.Unmarshal(query, &JSONQuery)
convertedResult, err := service.ConvertQuery(&JSONQuery)
// Assert that there is no error
assert.NoError(t, err)
// Assert that the result and the expected result are the same
Geurtjens,D. (Douwe Geurtjens)
committed
correctConvertedResult := `LET nodes = first(RETURN UNION_DISTINCT([],[]))
LET edges = first(RETURN UNION_DISTINCT([],[]))
RETURN {"vertices":nodes, "edges":edges }`
Geurtjens,D. (Douwe Geurtjens)
committed
regExCleaner := regexp.MustCompile(`\s+`)
correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
assert.Equal(t, correctCleanedResult, convertedCleanedResult)
Geurtjens,D. (Douwe Geurtjens)
committed
Tests two entities (two types) without a filter
Query description: Give me all parties connected to their respective parliament members
Geurtjens,D. (Douwe Geurtjens)
committed
func TestTwoEntitiesNoFilter(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
Geurtjens,D. (Douwe Geurtjens)
committed
"databaseName": "TweedeKamer",
"entities": [
0,
1
],
"relations": [
0
]
},
"entities": [
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parliament",
"ID": 0,
"constraints": []
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parties",
"ID": 1,
"constraints": []
],
"relations": [
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "member_of",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 0,
"toType": "entity",
Geurtjens,D. (Douwe Geurtjens)
committed
"toID": 1,
"constraints":[]
Geurtjens,D. (Douwe Geurtjens)
committed
}
Geurtjens,D. (Douwe Geurtjens)
committed
"groupBys": [],
"limit": 5000,
"modifiers": []
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON
json.Unmarshal(query, &JSONQuery)
convertedResult, err := service.ConvertQuery(&JSONQuery)
// Assert that there is no error
assert.NoError(t, err)
// Assert that the result and the expected result are the same
Geurtjens,D. (Douwe Geurtjens)
committed
correctConvertedResult := []byte(`LET result = (
FOR e_0 IN parliament
LET e1 = (
FOR e_1 IN parties
FOR r0 IN member_of
FILTER r0._from == e_0._id AND r0._to == e_1._id
FILTER length(e_1) != 0 AND length(r0) != 0
RETURN {"nodes":union_distinct([e_1], []), "rel": union_distinct([r0], [])}
)
FILTER length(e1) != 0 AND length(e_0) != 0
RETURN {"nodes":union_distinct(flatten(e1[**].nodes), [e_0]), "rel": union_distinct(flatten(e1[**].rel), [])}
)
let nodes = union_distinct(flatten(result[**].nodes),[])
let edges = union_distinct(flatten(result[**].rel),[])
return {"vertices":nodes,"edges":edges}`)
regExCleaner := regexp.MustCompile(`\s+`)
correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
assert.Equal(t, correctCleanedResult, convertedCleanedResult)
Geurtjens,D. (Douwe Geurtjens)
committed
Tests two entities (two types) with one entity filter
Query description: Give me all parties, with less than 10 seats, connected to their respective parliament members
Geurtjens,D. (Douwe Geurtjens)
committed
func TestTwoEntitiesOneEntityFilter(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
Geurtjens,D. (Douwe Geurtjens)
committed
"databaseName": "TweedeKamer",
"return": {
"entities": [
Geurtjens,D. (Douwe Geurtjens)
committed
0,
1
],
"relations": [
0
]
},
"entities": [
{
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parliament",
Geurtjens,D. (Douwe Geurtjens)
committed
"constraints": []
},
{
"name": "parties",
"ID": 1,
Geurtjens,D. (Douwe Geurtjens)
committed
"attribute": "seats",
"value": "10",
"dataType": "int",
"matchType": "LT"
}
]
}
],
"relations": [
{
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "member_of",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 0,
Geurtjens,D. (Douwe Geurtjens)
committed
"toType": "entity",
"toID": 1,
"constraints":[]
Geurtjens,D. (Douwe Geurtjens)
committed
"groupBys": [],
"limit": 5000,
"modifiers": []
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON
json.Unmarshal(query, &JSONQuery)
convertedResult, err := service.ConvertQuery(&JSONQuery)
// Assert that there is no error
assert.NoError(t, err)
// Assert that the result and the expected result are the same
Geurtjens,D. (Douwe Geurtjens)
committed
correctConvertedResult := []byte(`LET result = (
FOR e_0 IN parliament
LET e1 = (
FOR e_1 IN parties
FOR r0 IN member_of
FILTER e_1.seats < 10
FILTER r0._from == e_0._id AND r0._to == e_1._id
FILTER length(e_1) != 0 AND length(r0) != 0
RETURN {"nodes":union_distinct([e_1], []), "rel": union_distinct([r0], [])}
)
FILTER length(e1) != 0 AND length(e_0) != 0
RETURN {"nodes":union_distinct(flatten(e1[**].nodes), [e_0]), "rel": union_distinct(flatten(e1[**].rel), [])}
)
let nodes = union_distinct(flatten(result[**].nodes),[])
let edges = union_distinct(flatten(result[**].rel),[])
return {"vertices":nodes,"edges":edges}`)
regExCleaner := regexp.MustCompile(`\s+`)
correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
assert.Equal(t, correctCleanedResult, convertedCleanedResult)
Geurtjens,D. (Douwe Geurtjens)
committed
Tests two entities (two types) with two entity filters
Query description: Give me all parties, with less than 10 seats, connected to their respective parliament members, who are more than 45 years old
Geurtjens,D. (Douwe Geurtjens)
committed
func TestTwoEntitiesTwoEntityFilters(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
Geurtjens,D. (Douwe Geurtjens)
committed
"databaseName": "TweedeKamer",
"return": {
"entities": [
Geurtjens,D. (Douwe Geurtjens)
committed
0,
1
Geurtjens,D. (Douwe Geurtjens)
committed
"relations": [
0
]
},
"entities": [
{
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parliament",
Geurtjens,D. (Douwe Geurtjens)
committed
{
"attribute": "age",
"value": "45",
"dataType": "int",
"matchType": "GT"
}
]
},
{
"name": "parties",
"ID": 1,
"constraints": [
{
"attribute": "seats",
"value": "10",
"dataType": "int",
"matchType": "LT"
}
Geurtjens,D. (Douwe Geurtjens)
committed
"relations": [
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "member_of",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 0,
Geurtjens,D. (Douwe Geurtjens)
committed
"toType": "entity",
"toID": 1,
"constraints":[]
Geurtjens,D. (Douwe Geurtjens)
committed
"groupBys": [],
Geurtjens,D. (Douwe Geurtjens)
committed
"modifiers": []
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON
json.Unmarshal(query, &JSONQuery)
convertedResult, err := service.ConvertQuery(&JSONQuery)
// Assert that there is no error
assert.NoError(t, err)
// Assert that the result and the expected result are the same
Geurtjens,D. (Douwe Geurtjens)
committed
correctConvertedResult := []byte(`LET result = (
FOR e_0 IN parliament
FILTER e_0.age > 45
LET e1 = (
FOR e_1 IN parties
FOR r0 IN member_of
FILTER e_1.seats < 10
FILTER r0._from == e_0._id AND r0._to == e_1._id
FILTER length(e_1) != 0 AND length(r0) != 0
RETURN {"nodes":union_distinct([e_1], []), "rel": union_distinct([r0], [])}
)
FILTER length(e1) != 0 AND length(e_0) != 0
RETURN {"nodes":union_distinct(flatten(e1[**].nodes), [e_0]), "rel": union_distinct(flatten(e1[**].rel), [])}
)
let nodes = union_distinct(flatten(result[**].nodes),[])
let edges = union_distinct(flatten(result[**].rel),[])
return {"vertices":nodes,"edges":edges}`)
regExCleaner := regexp.MustCompile(`\s+`)
correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
assert.Equal(t, correctCleanedResult, convertedCleanedResult)
Geurtjens,D. (Douwe Geurtjens)
committed
Tests three entities (three types) without a filter
Query description: Give me all parties, connected to their respective parliament members, who are then connected to the resolutions they submitted
Geurtjens,D. (Douwe Geurtjens)
committed
func TestThreeEntitiesNoFilter(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
Geurtjens,D. (Douwe Geurtjens)
committed
"databaseName": "TweedeKamer",
"return": {
"entities": [
Geurtjens,D. (Douwe Geurtjens)
committed
0,
1,
2
Geurtjens,D. (Douwe Geurtjens)
committed
"relations": [
0,
1
]
},
"entities": [
{
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parliament",
Geurtjens,D. (Douwe Geurtjens)
committed
"constraints": []
},
{
"name": "parties",
"ID": 1,
"constraints": []
},
{
"name": "resolutions",
"ID": 2,
"constraints": []
Geurtjens,D. (Douwe Geurtjens)
committed
"relations": [
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "member_of",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 0,
"toType": "entity",
"toID": 1,
"constraints":[]
},
{
"ID": 1,
"name": "submits",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 0,
Geurtjens,D. (Douwe Geurtjens)
committed
"toType": "entity",
"toID": 2,
"constraints":[]
Geurtjens,D. (Douwe Geurtjens)
committed
"groupBys": [],
Geurtjens,D. (Douwe Geurtjens)
committed
"modifiers": []
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON
json.Unmarshal(query, &JSONQuery)
convertedResult, err := service.ConvertQuery(&JSONQuery)
// Assert that there is no error
assert.NoError(t, err)
// Assert that the result and the expected result are the same
Geurtjens,D. (Douwe Geurtjens)
committed
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
correctConvertedResult := []byte(`LET result = (
FOR e_1 IN parties
LET e0 = (
FOR e_0 IN parliament
FOR r0 IN member_of
FILTER r0._from == e_0._id AND r0._to == e_1._id
LET e2 = (
FOR e_2 IN resolutions
FOR r1 IN submits
FILTER r1._from == e_0._id AND r1._to == e_2._id
FILTER length(e_2) != 0 AND length(r1) != 0
RETURN {"nodes":union_distinct([e_2], []), "rel": union_distinct([r1], [])}
)
FILTER length(e2) != 0 AND length(e_0) != 0 AND length(r0) != 0
RETURN {"nodes":union_distinct(flatten(e2[**].nodes), [e_0]), "rel": union_distinct(flatten(e2[**].rel), [r0])}
)
FILTER length(e0) != 0 AND length(e_1) != 0
RETURN {"nodes":union_distinct(flatten(e0[**].nodes), [e_1]), "rel": union_distinct(flatten(e0[**].rel), [])}
)
let nodes = union_distinct(flatten(result[**].nodes),[])
let edges = union_distinct(flatten(result[**].rel),[])
return {"vertices":nodes,"edges":edges}`)
regExCleaner := regexp.MustCompile(`\s+`)
correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
assert.Equal(t, correctCleanedResult, convertedCleanedResult)
Geurtjens,D. (Douwe Geurtjens)
committed
Tests three entities (three types) with one entity filter
Query description: Give me all parties, connected to their respective parliament members, whose name has "Geert" in it (this results in only "Geert Wilders"), who are/is then connected to the resolutions they submitted
Geurtjens,D. (Douwe Geurtjens)
committed
func TestThreeEntitiesOneEntityFilter(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
Geurtjens,D. (Douwe Geurtjens)
committed
"databaseName": "TweedeKamer",
"return": {
"entities": [
Geurtjens,D. (Douwe Geurtjens)
committed
0,
1,
2
Geurtjens,D. (Douwe Geurtjens)
committed
0,
1
]
},
"entities": [
{
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parliament",
"ID": 0,
"constraints": [
{
"attribute": "name",
"value": "Geert",
"dataType": "string",
"matchType": "contains"
}
]
},
{
"name": "parties",
"ID": 1,
"constraints": []
},
{
"name": "resolutions",
"ID": 2,
"constraints": []
}
],
"relations": [
{
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "member_of",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 0,
Geurtjens,D. (Douwe Geurtjens)
committed
"toType": "entity",
"toID": 1,
"constraints":[]
},
{
"ID": 1,
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "submits",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 0,
"toType": "entity",
Geurtjens,D. (Douwe Geurtjens)
committed
"toID": 2,
"constraints":[]
Geurtjens,D. (Douwe Geurtjens)
committed
"groupBys": [],
Geurtjens,D. (Douwe Geurtjens)
committed
"modifiers": []
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON
json.Unmarshal(query, &JSONQuery)
convertedResult, err := service.ConvertQuery(&JSONQuery)
// Assert that there is no error
assert.NoError(t, err)
// Assert that the result and the expected result are the same
Geurtjens,D. (Douwe Geurtjens)
committed
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
correctConvertedResult := []byte(`LET result = (
FOR e_1 IN parties
LET e0 = (
FOR e_0 IN parliament
FOR r0 IN member_of
FILTER e_0.name LIKE "%Geert%"
FILTER r0._from == e_0._id AND r0._to == e_1._id
LET e2 = (
FOR e_2 IN resolutions
FOR r1 IN submits
FILTER r1._from == e_0._id AND r1._to == e_2._id
FILTER length(e_2) != 0 AND length(r1) != 0
RETURN {"nodes":union_distinct([e_2], []), "rel": union_distinct([r1], [])}
)
FILTER length(e2) != 0 AND length(e_0) != 0 AND length(r0) != 0
RETURN {"nodes":union_distinct(flatten(e2[**].nodes), [e_0]), "rel": union_distinct(flatten(e2[**].rel), [r0])}
)
FILTER length(e0) != 0 AND length(e_1) != 0
RETURN {"nodes":union_distinct(flatten(e0[**].nodes), [e_1]), "rel": union_distinct(flatten(e0[**].rel), [])}
)
let nodes = union_distinct(flatten(result[**].nodes),[])
let edges = union_distinct(flatten(result[**].rel),[])
return {"vertices":nodes,"edges":edges}`)
regExCleaner := regexp.MustCompile(`\s+`)
correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
assert.Equal(t, correctCleanedResult, convertedCleanedResult)
Geurtjens,D. (Douwe Geurtjens)
committed
Tests three entities (three types) with two entity filters
Query description: Give me all parties, connected to their respective parliament members, whose name has "Geert" in it (this results in only "Geert Wilders"), who are/is then connected to the resolutions they submitted, but only those submitted in May
Geurtjens,D. (Douwe Geurtjens)
committed
func TestThreeEntitiesTwoEntityFilters(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"databaseName": "TweedeKamer",
"return": {
"entities": [
0,
Geurtjens,D. (Douwe Geurtjens)
committed
1,
2
],
"relations": [
Geurtjens,D. (Douwe Geurtjens)
committed
0,
1
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parliament",
"ID": 0,
"constraints": [
{
"attribute": "name",
"value": "Geert",
"dataType": "string",
"matchType": "contains"
}
]
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parties",
Geurtjens,D. (Douwe Geurtjens)
committed
"constraints": []
},
{
"name": "resolutions",
"ID": 2,
"constraints": [
{
"attribute": "date",
"value": "mei",
"dataType": "string",
"matchType": "contains"
}
]
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "member_of",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 0,
"toType": "entity",
"toID": 1,
"constraints":[]
},
{
"ID": 1,
"name": "submits",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
Geurtjens,D. (Douwe Geurtjens)
committed
"fromID": 0,
"toType": "entity",
Geurtjens,D. (Douwe Geurtjens)
committed
"toID": 2,
"constraints":[]
Geurtjens,D. (Douwe Geurtjens)
committed
"groupBys": [],
Geurtjens,D. (Douwe Geurtjens)
committed
"modifiers": []
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON
json.Unmarshal(query, &JSONQuery)
Geurtjens,D. (Douwe Geurtjens)
committed
convertedResult, err := service.ConvertQuery(&JSONQuery)
// Assert that there is no error
assert.NoError(t, err)
// Assert that the result and the expected result are the same
Geurtjens,D. (Douwe Geurtjens)
committed
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
correctConvertedResult := []byte(`LET result = (
FOR e_1 IN parties
LET e0 = (
FOR e_0 IN parliament
FOR r0 IN member_of
FILTER e_0.name LIKE "%Geert%"
FILTER r0._from == e_0._id AND r0._to == e_1._id
LET e2 = (
FOR e_2 IN resolutions
FOR r1 IN submits
FILTER e_2.date LIKE "%mei%"
FILTER r1._from == e_0._id AND r1._to == e_2._id
FILTER length(e_2) != 0 AND length(r1) != 0
RETURN {"nodes":union_distinct([e_2], []), "rel": union_distinct([r1], [])}
)
FILTER length(e2) != 0 AND length(e_0) != 0 AND length(r0) != 0
RETURN {"nodes":union_distinct(flatten(e2[**].nodes), [e_0]), "rel": union_distinct(flatten(e2[**].rel), [r0])}
)
FILTER length(e0) != 0 AND length(e_1) != 0
RETURN {"nodes":union_distinct(flatten(e0[**].nodes), [e_1]), "rel": union_distinct(flatten(e0[**].rel), [])}
)
let nodes = union_distinct(flatten(result[**].nodes),[])
let edges = union_distinct(flatten(result[**].rel),[])
return {"vertices":nodes,"edges":edges}`)
regExCleaner := regexp.MustCompile(`\s+`)
correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
assert.Equal(t, correctCleanedResult, convertedCleanedResult)
Geurtjens,D. (Douwe Geurtjens)
committed
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
Tests five entities (three types) with four entity filters
Query description: Give me all parties, which have less than 10 seats, connected to their respective parliament members, whose name has "A" in it, who are/is then connected to the resolutions they submitted, but only those submitted in May, which are then also connected to all other persons who were part of that submission, who are part of the "VVD"
Translator's note: This returns a member of the PvdA who submitted a motion alongside a member of the VVD
hmmmmmmmmmmmmmmmmmmmmmmmmmmyo+/oooooooooooooooo+/+oymmmmmmmmmhso++/+++oo+++/++ohmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmmmmmmmmmmmmmmmmmho/+ooooooooooooooooooooooo+/oymdyo+/+ooooooooooooooooo++ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmmmmmmmmmmmmmmmh++ooooooooooooooooooooooooooooo+/:+ooooooooooooooooooooooo++dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmmmmmmmmmmmmmdo/ooooooooooooooooooooooooooooooooo//oooooooooooooooooooooooo+/dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmmmmmmmmmmmmy/+ooooooooooooo++////////////++oooooo//ooooooooooooooooooooooooo/dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmmmmmmmmmmmo/ooooooooooo+///++++oooooooo++++///++oo:+oooooooooooooooooooooooo++mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmmmmmmmmmd++ooooooooo+//++oooooooooooooooooooo++////:+++////////////////////++:ydmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmmmmmmmmd/+oooooooooo++ooooooooooooooooooooooooooo+/:/++ooooooooooooooooo+o+++++++oshmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmmmmmmmd/+oooooooooooooooooooooooooooooo+++++++++++++//+ooooooooooooooooooooooooooo+++ohmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmmmmmmm++oooooooooooooooooooooooo+++////++++++++++++++/://+ooooo+++++////////////////++//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmmmmmms/oooooooooooooooooooooo++//+++++//////////////++++++:++///++/++++///////////////+/+ohmmmmNmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmmmdhs++:ooooooooooooooooooo+++//+++////+++++sosysssso+++++//://////++++++++//////+o+++++///+/smmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmmms+++o+/ooooooooooooooo+///+++++//+osyy+:+:...-:yNMMNmddyso++/++ooooooyho--o-````-+dmddyo+++//ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmmd++oooo:+oooooooooooo+++++++////+oydNMy. `s: `:-` :mMMMMMMMMNmy/oooydNMMo` .o- .+:` -mMMMNdhhso/ommmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmmmh/oooooo:ooooooooooooo//+++++oooymMMMMN. .. :dh. +MMMMMMMMMMMoodNMMMMN` -. :hs` oMMMMMMMMNyommmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmdy/ooooooo/ooooooooooooo+//////:yNMMMMMMm` :- ` :MMMMMMMMMMNsMMMMMMMd -. /MMMMMMMMMN+mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hmy/ooooooooooooooooooooooooooooo++smNMMMMN. `sMMMMMMMMMNsmMMMMMMMm. .hMMMMMMNmhshmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
hh/ooooooooooooooooooooooooooooooo+o++oymNNd:` `:hMMMMMNNmyo+:sdmNNNNMMd:`` `+dNmmhysoo++mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
y/oooooooooooooooooooooooooooooooo///+o+++osys+/://+shdddysoo+++oo+:++++++ooosso/-----/++/++++o++oydmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
-+ooooooooooooooooooooooooooooooooooo+////+++++++////++++oooo+/////ooooooooooooooooooooooooooo+ommmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/ooooooooooooooooooooooooooooooooooooooooo++/////////////////+oooooooooooooooooooooooooooooo++ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/ooooooooooooooooooooooooooooooooooooooooooooooooooooooo+/+//ooooooooo+/+oooooooooooooo+/ossdmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/oooooooooooooooooooooooooooooooooooooooooooooooooo++///+oooooooooooooo+////:////////////ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/oooooooooooooooooooooooooooooooooooooooooooooo+///+oooooooooooooooooooooooo+/+oooooooooo++ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo++dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+/dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+/mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo/ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/ooooooooooooooooooooooooooooooo++++++++++ooooooooooooooooooooooooooooooooooooooooooooooooooooo/mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/oooooooooooooooooooooooooooo+//++++++++///////++++++ooooooooooooooooooooooooooooooooooooo+++///+smmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/oooooooooooooooooooooooooo+/++oooooooooooooo++++++////////+++++++oooooooooooooooo+++++////+++oo+:mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/ooooooooooooooooooooooooo+:+oooo+///////++++++ooooooooo++++++++///////////////////++++++ooooo+++ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/ooooooooooooooooooooooooo:+ooooo++++++++++++//////++++++++ooooooooooooooooooooooooooooo++++++oydmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/ooooooooooooooooooooooooo+/++++oooooooooooooooo++++++++///////////+/++++++++++////////////+:smmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/ooooooooooooooooooooo/+ooo+///////////////+++++++oooooooooooo+++++++++++++++++++++++ooooooo+/mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
/+ooooooooooooooooooooo//ooooooooooooooooo++++++/////++++++++++++++oooooooooooooooooooooo++++hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
y++ooooooooooooooooooooo+//+++ooooooooooooooooooooooo++++////////////////////////++//++++osymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
yd//++ooooooooooooooooooooo+++oooooooooooooooooooooooooooooooooooooooooooo++++++++//sddmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
::::////++oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+++ohmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
:/:::://+/////+oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+++oymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
://////::://+++///////+++ooooooooooooooooooooooooooooooooooooooooooooo++++sydmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
://////////::::/++ooo+++////////////++++++ooooooooooooooooo+++++/////shdmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
-///////////////::::://+++oooooooooo+++++////////////////////+++/::::odmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
Geurtjens,D. (Douwe Geurtjens)
committed
func TestFiveEntitiesFourEntityFilters(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
Geurtjens,D. (Douwe Geurtjens)
committed
"databaseName": "TweedeKamer",
"return": {
"entities": [
Geurtjens,D. (Douwe Geurtjens)
committed
0,
1,
2,
3,
4
Geurtjens,D. (Douwe Geurtjens)
committed
0,
1,
2,
3
]
},
"entities": [
{
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parliament",
Geurtjens,D. (Douwe Geurtjens)
committed
"constraints": [
{
"attribute": "name",
"value": "A",
"dataType": "string",
"matchType": "contains"
}
]
},
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parties",
Geurtjens,D. (Douwe Geurtjens)
committed
"constraints": [
{
"attribute": "seats",
"value": "10",
"dataType": "int",
"matchType": "LT"
}
]
},
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "resolutions",
"ID": 2,
Geurtjens,D. (Douwe Geurtjens)
committed
"attribute": "date",
"value": "mei",
Geurtjens,D. (Douwe Geurtjens)
committed
"matchType": "contains"
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parliament",
"ID": 3,
"constraints":[]
},
{
"name": "parties",
"ID": 4,
Geurtjens,D. (Douwe Geurtjens)
committed
"attribute": "name",
"value": "Volkspartij voor Vrijheid en Democratie",
Geurtjens,D. (Douwe Geurtjens)
committed
"matchType": "=="
}
]
}
],
"relations": [
{
Geurtjens,D. (Douwe Geurtjens)
committed
"ID": 0,
"name": "member_of",
"depth": {
"min": 1,
Geurtjens,D. (Douwe Geurtjens)
committed
"max": 1
"fromType": "entity",
Geurtjens,D. (Douwe Geurtjens)
committed
"fromID": 0,
"toType": "entity",
Geurtjens,D. (Douwe Geurtjens)
committed
"toID": 1,
"constraints": []
},
Geurtjens,D. (Douwe Geurtjens)
committed
"ID": 1,
"name": "submits",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 0,
Geurtjens,D. (Douwe Geurtjens)
committed
"toType": "entity",
"toID": 2,
"constraints": []
},
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "submits",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 3,
"toType": "entity",
"toID": 2,
"constraints": []
},
{
"ID": 3,
"name": "member_of",
"depth": {
"min": 1,
"max": 1
},
"fromType": "entity",
"fromID": 3,
"toType": "entity",
"toID": 4,
"constraints": []
Geurtjens,D. (Douwe Geurtjens)
committed
"groupBys": [],
"limit": 5000,
"modifiers": []
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON
json.Unmarshal(query, &JSONQuery)
convertedResult, err := service.ConvertQuery(&JSONQuery)
// Assert that there is no error
assert.NoError(t, err)
// Assert that the result and the expected result are the same
Geurtjens,D. (Douwe Geurtjens)
committed
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
correctConvertedResult := []byte(`LET result = (
FOR e_1 IN parties
FILTER e_1.seats < 10
LET e0 = (
FOR e_0 IN parliament
FOR r0 IN member_of
FILTER e_0.name LIKE "%A%"
FILTER r0._from == e_0._id AND r0._to == e_1._id
LET e2 = (
FOR e_2 IN resolutions
FOR r1 IN submits
FILTER e_2.date LIKE "%mei%"
FILTER r1._from == e_0._id AND r1._to == e_2._id
LET e3 = (
FOR e_3 IN parliament
FOR r2 IN submits
FILTER r2._from == e_3._id AND r2._to == e_2._id
LET e4 = (
FOR e_4 IN parties
FOR r3 IN member_of
FILTER e_4.name == "Volkspartij voor Vrijheid en Democratie"
FILTER r3._from == e_3._id AND r3._to == e_4._id
FILTER length(e_4) != 0 AND length(r3) != 0
RETURN {"nodes":union_distinct([e_4], []), "rel": union_distinct([r3], [])}
)
FILTER length(e4) != 0 AND length(e_3) != 0 AND length(r2) != 0
RETURN {"nodes":union_distinct(flatten(e4[**].nodes), [e_3]), "rel": union_distinct(flatten(e4[**].rel), [r2])}
)
FILTER length(e3) != 0 AND length(e_2) != 0 AND length(r1) != 0
RETURN {"nodes":union_distinct(flatten(e3[**].nodes), [e_2]), "rel": union_distinct(flatten(e3[**].rel), [r1])}
)
FILTER length(e2) != 0 AND length(e_0) != 0 AND length(r0) != 0
RETURN {"nodes":union_distinct(flatten(e2[**].nodes), [e_0]), "rel": union_distinct(flatten(e2[**].rel), [r0])}
)
FILTER length(e0) != 0 AND length(e_1) != 0
RETURN {"nodes":union_distinct(flatten(e0[**].nodes), [e_1]), "rel": union_distinct(flatten(e0[**].rel), [])}
)
let nodes = union_distinct(flatten(result[**].nodes),[])
let edges = union_distinct(flatten(result[**].rel),[])
return {"vertices":nodes,"edges":edges}`)
regExCleaner := regexp.MustCompile(`\s+`)
correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
assert.Equal(t, correctCleanedResult, convertedCleanedResult)
Geurtjens,D. (Douwe Geurtjens)
committed
Tests five entities (four types) with three entity filters and one junction
Query description: Give me all parties, with less than 10 seats, connected to their respective parliament members, who are then connected to the resolutions they submitted, but only those submitted in May, and connected to the comissions they're in, which are then connected to all of their members, but only those with "Geert" in their name (resulting in only "Geert Wilders")
Geurtjens,D. (Douwe Geurtjens)
committed
func TestSingleJunctionFiveEntitiesThreeEntityFilters(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0,
1,
Geurtjens,D. (Douwe Geurtjens)
committed
2,
3,
4
],
"relations": [
0,
Geurtjens,D. (Douwe Geurtjens)
committed
1,
2,
3
]
},
"entities": [
{
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parliament",
Geurtjens,D. (Douwe Geurtjens)
committed
"constraints": [
{
"attribute": "name",
"value": "Geert",
"dataType": "string",
"matchType": "contains"
}
]
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "commissions",
Geurtjens,D. (Douwe Geurtjens)
committed
"constraints": []
Geurtjens,D. (Douwe Geurtjens)
committed
"name": "parliament",
Geurtjens,D. (Douwe Geurtjens)
committed
"constraints": []
},
{
"name": "parties",
"ID": 3,
"constraints": [
{
"attribute": "seats",
"value": "10",
"dataType": "int",
"matchType": "LT"
}
]
},
{
"name": "resolutions",
"ID": 4,
"constraints": [
{
"attribute": "date",