Skip to content
Snippets Groups Projects
convertQuery_test.go 72.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • LoLo5689's avatar
    LoLo5689 committed
    /*
    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)
    */
    
    
    	"git.science.uu.nl/graphpolaris/query-conversion/entity"
    
    	"github.com/stretchr/testify/assert"
    )
    
    
    LoLo5689's avatar
    LoLo5689 committed
    /*
    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
    
    	correctConvertedResult := `LET nodes = first(RETURN UNION_DISTINCT([],[]))
    
    LET edges = first(RETURN UNION_DISTINCT([],[]))
    RETURN {"vertices":nodes, "edges":edges }`
    
    	regExCleaner := regexp.MustCompile(`\s+`)
    	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
    	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
    	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
    
    LoLo5689's avatar
    LoLo5689 committed
    
    /*
    
    Tests two entities (two types) without a filter
    Query description: Give me all parties connected to their respective parliament members
    
    LoLo5689's avatar
    LoLo5689 committed
    	t: *testing.T, makes go recognise this as a test
    */
    
    	// Setup for test
    	// Create query conversion service
    	service := NewService()
    
    	query := []byte(`{
    
    				"depth": {
    					"min": 1,
    					"max": 1
    				},
    				"fromType": "entity",
    				"fromID": 0,
    				"toType": "entity",
    
    		"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 := []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)
    
    LoLo5689's avatar
    LoLo5689 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
    
    LoLo5689's avatar
    LoLo5689 committed
    	t: *testing.T, makes go recognise this as a test
    */
    
    	// Setup for test
    	// Create query conversion service
    	service := NewService()
    
    	query := []byte(`{
    
    		"return": {
    			"entities": [
    
    				"depth": {
    					"min": 1,
    					"max": 1
    				},
    
    				"fromType": "entity",
    				"fromID": 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 := []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)
    
    LoLo5689's avatar
    LoLo5689 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
    
    LoLo5689's avatar
    LoLo5689 committed
    	t: *testing.T, makes go recognise this as a test
    */
    
    	// Setup for test
    	// Create query conversion service
    	service := NewService()
    
    	query := []byte(`{
    
    		"return": {
    			"entities": [
    
    					{
    						"attribute": "age",
    						"value": "45",
    						"dataType": "int",
    						"matchType": "GT"
    					}
    				]
    			},
    			{
    				"name": "parties",
    				"ID": 1,
    				"constraints": [
    					{
    						"attribute": "seats",
    						"value": "10",
    						"dataType": "int",
    						"matchType": "LT"
    					}
    
    				"fromType": "entity",
    				"fromID": 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 := []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)
    
    LoLo5689's avatar
    LoLo5689 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
    
    LoLo5689's avatar
    LoLo5689 committed
    	t: *testing.T, makes go recognise this as a test
    */
    
    	// Setup for test
    	// Create query conversion service
    	service := NewService()
    
    	query := []byte(`{
    
    		"return": {
    			"entities": [
    
    				"constraints": []
    			},
    			{
    				"name": "parties",
    				"ID": 1,
    				"constraints": []
    			},
    			{
    				"name": "resolutions",
    				"ID": 2,
    				"constraints": []
    
    				"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,
    
    	// 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 := []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)
    
    LoLo5689's avatar
    LoLo5689 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
    
    LoLo5689's avatar
    LoLo5689 committed
    	t: *testing.T, makes go recognise this as a test
    */
    
    	// Setup for test
    	// Create query conversion service
    	service := NewService()
    
    	query := []byte(`{
    
    		"return": {
    			"entities": [
    
    				"name": "parliament",
    				"ID": 0,				
    				"constraints": [
    					{
    						"attribute": "name",
    						"value": "Geert",
    						"dataType": "string",
    						"matchType": "contains"
    					}
    				]
    			},
    			{
    				"name": "parties",
    				"ID": 1,
    				"constraints": []
    			},
    			{
    				"name": "resolutions",
    				"ID": 2,
    				"constraints": []
    
    				"depth": {
    					"min": 1,
    					"max": 1
    				},
    
    				"fromType": "entity",
    				"fromID": 0,
    
    				"fromID": 0,
    				"toType": "entity",
    
    	// 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 := []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)
    
    LoLo5689's avatar
    LoLo5689 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
    
    LoLo5689's avatar
    LoLo5689 committed
    	t: *testing.T, makes go recognise this as a test
    */
    
    	// Setup for test
    	// Create query conversion service
    	service := NewService()
    
    	query := []byte(`{
    		"databaseName": "TweedeKamer",
    		"return": {
    
    				"name": "parliament",
    				"ID": 0,				
    				"constraints": [
    					{
    						"attribute": "name",
    						"value": "Geert",
    						"dataType": "string",
    						"matchType": "contains"
    					}
    				]
    
    				"constraints": []
    			},
    			{
    				"name": "resolutions",
    				"ID": 2,
    				"constraints": [
    					{
    						"attribute": "date",
    						"value": "mei",
    						"dataType": "string",
    						"matchType": "contains"
    					}
    				]
    
    				"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",
    
    		"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 := []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)
    
    LoLo5689's avatar
    LoLo5689 committed
    
    /*
    
    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
    
    
    LoLo5689's avatar
    LoLo5689 committed
    	t: *testing.T, makes go recognise this as a test
    */
    
    	// Setup for test
    	// Create query conversion service
    	service := NewService()
    
    	query := []byte(`{
    
    		"return": {
    			"entities": [
    
    				"constraints": [
    					{
    						"attribute": "name",
    						"value": "A",
    						"dataType": "string",
    						"matchType": "contains"
    					}
    				]
    			},
    
    				"constraints": [
    					{
    						"attribute": "seats",
    						"value": "10",
    						"dataType": "int",
    						"matchType": "LT"
    					}
    				]
    			},
    
    Fjodor's avatar
     
    Fjodor committed
    						"dataType": "string",
    
    						"attribute": "name",
    						"value": "Volkspartij voor Vrijheid en Democratie",
    
    Fjodor's avatar
     
    Fjodor committed
    						"dataType": "string",
    
    				"fromType": "entity",
    				"fromID": 0,
    
    				"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": []
    
    	// 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 := []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)
    
    LoLo5689's avatar
    LoLo5689 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")
    
    LoLo5689's avatar
    LoLo5689 committed
    	t: *testing.T, makes go recognise this as a test
    */
    
    func TestSingleJunctionFiveEntitiesThreeEntityFilters(t *testing.T) {
    
    	// Setup for test
    	// Create query conversion service
    	service := NewService()
    
    	query := []byte(`{
    		"return": {
    			"entities": [
    				0,
    				1,
    
    				"constraints": [
    					{
    						"attribute": "name",
    						"value": "Geert",
    						"dataType": "string",
    						"matchType": "contains"
    					}
    				]
    
    				"constraints": []
    			},
    			{
    				"name": "parties",
    				"ID": 3,
    				"constraints": [
    					{
    						"attribute": "seats",
    						"value": "10",
    						"dataType": "int",
    						"matchType": "LT"
    					}
    				]
    			},
    			{
    				"name": "resolutions",
    				"ID": 4,
    				"constraints": [
    					{
    						"attribute": "date",
    						"value": "mei",