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"
"strings"
"testing"
"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": [],
"limit": 5000
}`)
// 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
correctConvertedResult := `
LET nodes = first(RETURN UNION_DISTINCT([],[]))
LET edges = first(RETURN UNION_DISTINCT([],[]))
RETURN {"vertices":nodes, "edges":edges }`
assert.Equal(t, correctConvertedResult, *convertedResult)
}
/*
Tests multiple entity types
t: *testing.T, makes go recognise this as a test
*/
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
func TestMultipleEntityTypes(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"databaseName": "test",
"return": {
"entities": [
0,
1
],
"relations": [
0
]
},
"entities": [
{
"type": "kamerleden",
"constraints": [
{
"attribute": "partij",
"value": "GL",
"dataType": "text",
"matchType": "exact"
}
]
},
{
"type": "partijen",
"constraints": [
{
"attribute": "zetels",
"value": "6",
"dataType": "number",
"matchType": "GT"
}
]
}
],
"relations": [
{
"type": "lid_van",
"depth": {
"min": 1,
"max": 1
},
"entityFrom": 0,
"entityTo": 1,
"constraints": []
}
],
"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
correctConvertedResult := "WITH partijen\nLET n0 = (\n\tFOR x IN kamerleden \n\tFILTER x.partij == \"GL\" \n\tRETURN x\n)\nLET r0 = (\n\tFOR x IN n0 \n\tFOR v, e, p IN 1..1 OUTBOUND x lid_van \n\tOPTIONS { uniqueEdges: \"path\" }\n\tFILTER v.zetels > 6 \n\tLIMIT 5000 \nRETURN DISTINCT p )\n\nLET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))\nLET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))\nRETURN {\"vertices\":nodes, \"edges\":edges }"
cleanedResult := strings.ReplaceAll(correctConvertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
convertedCleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
convertedCleanedResult = strings.ReplaceAll(convertedCleanedResult, "\t", "")
assert.Equal(t, convertedCleanedResult, cleanedResult)
}
/*
Tests a query with one attribute
t: *testing.T, makes go recognise this as a test
*/
func TestEntityOneAttributeQuery(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0
],
"relations": []
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "state",
"value": "HI",
"matchType": "exact"
}
]
}
],
"relations": [],
"limit": 5000
}`)
// 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
correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET nodes = first(RETURN UNION_DISTINCT(n0,[],[]))LET edges = first(RETURN UNION_DISTINCT([],[]))RETURN {"vertices":nodes, "edges":edges }`
cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
assert.Equal(t, correctConvertedResult, cleanedResult)
}
/*
Test a relation with a constraint
t: *testing.T, makes go recognise this as a test
*/
func TestRelationWithConstraint(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0
],
"relations": [
0
]
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "state",
"value": "HI",
"matchType": "exact"
}
]
}
],
"relations": [
{
"type": "flights",
"depth": {
"min": 1,
"max": 1
},
"entityFrom": 0,
"entityTo": -1,
"constraints": [
{
"attribute": "Day",
"value": "15",
"matchType": "EQ"
}
]
}
],
"limit": 5000
}`)
// 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
correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER p.edges[*].Day ALL == 15 LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }`
cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
assert.Equal(t, correctConvertedResult, cleanedResult)
}
/*
Tests the count modifier
t: *testing.T, makes go recognise this as a test
*/
func TestModifierCountEntity(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0
],
"relations": []
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "state",
"value": "HI",
"matchType": "exact"
}
]
}
],
"relations": [],
"limit": 5000,
"modifiers": [
{
"type": "COUNT",
"selectedType": "entity",
"id": 0,
"attributeIndex": -1
}
]
}`)
// 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
correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)RETURN LENGTH (n0)`
cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
assert.Equal(t, correctConvertedResult, cleanedResult)
}
/*
Tests the count modifer with an attribute
t: *testing.T, makes go recognise this as a test
*/
func TestModifierCountEntityAttribute(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0
],
"relations": []
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "state",
"value": "HI",
"matchType": "exact"
}
]
}
],
"relations": [],
"limit": 5000,
"modifiers": [
{
"type": "SUM",
"selectedType": "entity",
"id": 0,
"attributeIndex": 0
}
]
}`)
// 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
correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)RETURN SUM (n0[*].state)`
cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
assert.Equal(t, correctConvertedResult, cleanedResult)
}
/*
Tests the count modifier on a relation
t: *testing.T, makes go recognise this as a test
*/
func TestModifierCountRelation(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0
],
"relations": [
0
]
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "state",
"value": "HI",
"matchType": "exact"
}
]
}
],
"relations": [
{
"type": "flights",
"depth": {
"min": 1,
"max": 1
},
"entityFrom": 0,
"entityTo": -1,
"constraints": [
{
"attribute": "Day",
"value": "15",
"matchType": "EQ"
}
]
}
],
"limit": 5000,
"modifiers": [
{
"type": "COUNT",
"selectedType": "relation",
"id": 0,
"attributeIndex": -1
}
]
}`)
// 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
correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER p.edges[*].Day ALL == 15 RETURN DISTINCT p )RETURN LENGTH (unique(r0[*].edges[**]))`
cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
assert.Equal(t, correctConvertedResult, cleanedResult)
}
/*
Tests the count modifier with an entity swap
t: *testing.T, makes go recognise this as a test
*/
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
func TestModifierCountEntitySwap(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"databaseName": "TweedeKamer",
"return": {
"entities": [
0,
1
],
"relations": [
0
]
},
"entities": [
{
"type": "partijen",
"constraints": []
},
{
"type": "kamerleden",
"constraints": []
}
],
"relations": [
{
"type": "lid_van",
"depth": {
"min": 1,
"max": 1
},
"entityFrom": 1,
"entityTo": 0,
"constraints": []
}
],
"limit": 5000,
"modifiers": [
{
"type": "COUNT",
"selectedType": "entity",
"selectedTypeId": 1,
"attributeIndex": -1
}
]
}`)
// 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
correctConvertedResult := `WITH partijenLET n1 = (FOR x IN kamerleden RETURN x)LET r0 = (FOR x IN n1 FOR v, e, p IN 1..1 OUTBOUND x lid_van OPTIONS { uniqueEdges: "path" }RETURN DISTINCT p )RETURN LENGTH (unique(r0[*].vertices[0]))`
cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
assert.Equal(t, correctConvertedResult, cleanedResult)
}
/*
Tests the count modifier on a relation and attribute
t: *testing.T, makes go recognise this as a test
*/
func TestModifierCountRelationAttribute(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0
],
"relations": [
0
]
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "state",
"value": "HI",
"matchType": "exact"
}
]
}
],
"relations": [
{
"type": "flights",
"depth": {
"min": 1,
"max": 1
},
"entityFrom": 0,
"entityTo": -1,
"constraints": [
{
"attribute": "Day",
"value": "15",
"matchType": "EQ"
}
]
}
],
"limit": 5000,
"modifiers": [
{
"type": "AVG",
"selectedType": "relation",
"id": 0,
"attributeIndex": 0
}
]
}`)
// 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
correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER p.edges[*].Day ALL == 15 RETURN DISTINCT p )RETURN AVG (r0[*].edges[**].Day)`
cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
assert.Equal(t, correctConvertedResult, cleanedResult)
}
/*
Tests a relation with an in out constraint
t: *testing.T, makes go recognise this as a test
*/
func TestRelationWithInOutConstraint(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0,
1
],
"relations": [
0
]
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "city",
"value": "San Francisco",
"matchType": "exact"
}
]
},
{
"type": "airports",
"constraints": [
{
"attribute": "state",
"value": "HI",
"matchType": "exact"
}
]
}
],
"relations": [
{
"type": "flights",
"depth": {
"min": 1,
"max": 3
},
"entityFrom": 1,
"entityTo": 0,
"constraints": [
{
"attribute": "Day",
"value": "15",
"matchType": "EQ"
}
]
}
],
"limit": 5000
}`)
// 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
correctConvertedResult := `LET n1 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n1 FOR v, e, p IN 1..3 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER v.city == "San Francisco" FILTER p.edges[*].Day ALL == 15 LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }`
cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
assert.Equal(t, correctConvertedResult, cleanedResult)
}
/*
Tests two relations
t: *testing.T, makes go recognise this as a test
*/
func TestTwoRelations(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0,
1,
2
],
"relations": [
0,
1
]
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "city",
"value": "New York",
"matchType": "exact"
}
]
},
{
"type": "airports",
"constraints": [
{
"attribute": "city",
"value": "San Francisco",
"matchType": "exact"
}
]
},
{
"type": "airports",
"constraints": [
{
"attribute": "state",
"value": "HI",
"matchType": "exact"
}
]
}
],
"relations": [
{
"type": "flights",
"depth": {
"min": 1,
"max": 3
},
"entityFrom": 2,
"entityTo": 1,
"constraints": [
{
"attribute": "Day",
"value": "15",
"matchType": "EQ"
}
]
},
{
"type": "flights",
"depth": {
"min": 1,
"max": 1
},
"entityFrom": 0,
"entityTo": -1,
"constraints": []
}
],
"limit": 5000
}`)
// 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
correctConvertedResult := `LET n2 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n2 FOR v, e, p IN 1..3 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER v.city == "San Francisco" FILTER p.edges[*].Day ALL == 15 LIMIT 5000 RETURN DISTINCT p )LET n0 = (FOR x IN airports FILTER x.city == "New York" RETURN x)LET r1 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), flatten(r1[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), flatten(r1[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }`
cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
assert.Equal(t, correctConvertedResult, cleanedResult)
}
/*
Tests a relation with only a to node
t: *testing.T, makes go recognise this as a test
*/
func TestRelationWithOnlyToNode(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0
],
"relations": [
0
]
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "city",
"value": "San Francisco",
"matchType": "exact"
}
]
}
],
"relations": [
{
"type": "flights",
"depth": {
"min": 1,
"max": 1
},
"entityFrom": -1,
"entityTo": 0,
"constraints": []
}
],
"limit": 5000
}`)
// 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
correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.city == "San Francisco" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 INBOUND x flights OPTIONS { uniqueEdges: "path" }LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }`
cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
assert.Equal(t, correctConvertedResult, cleanedResult)
}
/*
Tests too manu return entities
t: *testing.T, makes go recognise this as a test
*/
func TestTooManyReturnEntities(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0,
1,
2
],
"relations": [
0
]
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "city",
"value": "San Francisco",
"matchType": "exact"
}
]
}
],
"relations": [
{
"type": "flights",
"depth": {
"min": 1,
"max": 1
},
"entityFrom": -1,
"entityTo": 0,
"constraints": []
}
],
"limit": 5000
}`)
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON
json.Unmarshal(query, &JSONQuery)
_, err := service.ConvertQuery(&JSONQuery)
// Assert that there is no error
assert.Equal(t, errors.New("non-existing entity referenced in return"), err)
}
/*
Tests too manu return relations
t: *testing.T, makes go recognise this as a test
*/
func TestTooManyReturnRelations(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0
],
"relations": [
0,
1,
2
]
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "city",
"value": "San Francisco",
"matchType": "exact"
}
]
}
],
"relations": [
{
"type": "flights",
"depth": {
"min": 1,
"max": 1
},
"entityFrom": -1,
"entityTo": 0,
"constraints": []
}
],
"limit": 5000
}`)
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON
json.Unmarshal(query, &JSONQuery)
_, err := service.ConvertQuery(&JSONQuery)
// Assert that there is no error
assert.Equal(t, errors.New("non-existing relation referenced in return"), err)
}
/*
Tests negative return entities
t: *testing.T, makes go recognise this as a test
*/
func TestNegativeReturnEntities(t *testing.T) {
// Setup for test
// Create query conversion service
service := NewService()
query := []byte(`{
"return": {
"entities": [
0,
-1
],
"relations": [
0,
1,
2
]
},
"entities": [
{
"type": "airports",
"constraints": [
{
"attribute": "city",
"value": "San Francisco",
"matchType": "exact"
}
]
}
],
"relations": [
{
"type": "flights",
"depth": {
"min": 1,
"max": 1
},
"entityFrom": -1,
"entityTo": 0,
"constraints": []
}
],
"limit": 5000
}`)
// Unmarshall the incoming message into an IncomingJSONQuery object
var JSONQuery entity.IncomingQueryJSON