| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 | /* * EliasDB * * Copyright 2016 Matthias Ladkau. All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */package interpreterimport "testing"func TestDateFunctions(t *testing.T) {	gm, _ := dateGraph()	rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))	if _, err := getResult("get datetest", `Labels: Datetest Key, Rfc3339 Value, Naive Value, Datetest Name, UnixFormat: auto, auto, auto, auto, autoData: 1:n:key, 1:n:RFC3339_value, 1:n:naive_value, 1:n:name, 1:n:unix000, 2012-10-09T19:00:55Z, 2012-10-09, date1, 1349809255001, 2012-10-12T19:00:55+02:00, 2012-10-12, date2, 1350061255`[1:], rt, true); err != nil {		t.Error(err)		return	}	// Test default conversion to RFC3339	if _, err := getResult("get datetest where @parseDate(RFC3339_value) = unix", `Labels: Datetest Key, Rfc3339 Value, Naive Value, Datetest Name, UnixFormat: auto, auto, auto, auto, autoData: 1:n:key, 1:n:RFC3339_value, 1:n:naive_value, 1:n:name, 1:n:unix000, 2012-10-09T19:00:55Z, 2012-10-09, date1, 1349809255001, 2012-10-12T19:00:55+02:00, 2012-10-12, date2, 1350061255`[1:], rt, true); err != nil {		t.Error(err)		return	}	// The format string '2006-01-02' interprets <year>-<month>-<day>	// The string 2012-10-12 is interpreted as 2012-10-12 00:00:00 +0000 UTC	if _, err := getResult("get datetest where @parseDate(naive_value, '2006-01-02') > @parseDate('2012-10-11', '2006-01-02')", `Labels: Datetest Key, Rfc3339 Value, Naive Value, Datetest Name, UnixFormat: auto, auto, auto, auto, autoData: 1:n:key, 1:n:RFC3339_value, 1:n:naive_value, 1:n:name, 1:n:unix001, 2012-10-12T19:00:55+02:00, 2012-10-12, date2, 1350061255`[1:], rt, true); err != nil {		t.Error(err)		return	}}func TestCountFunctions(t *testing.T) {	gm, _ := songGraphGroups()	rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))	rt2 := NewLookupRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))	if _, err := getResult("get Author traverse :::Song end show name, 2:n:name", `Labels: Author Name, NameFormat: auto, autoData: 1:n:name, 2:n:nameHans, MyOnlySong3John, Aria1John, Aria2John, Aria3John, Aria4Mike, DeadSong2Mike, FightSong4Mike, LoveSong3Mike, StrangeSong1`[1:], rt, true); err != nil {		t.Error(err)		return	}	if _, err := getResult("get Author show name, @count(1, :::Song) AS mycount format xxx", `Labels: Author Name, mycountFormat: auto, xxxData: 1:n:name, 1:func:count()Hans, 1John, 4Mike, 4`[1:], rt, true); err != nil {		t.Error(err)		return	}	if _, err := getResult("get group traverse ::: end show key, @count(2, :::Author)", `Labels: Group Key, CountFormat: auto, autoData: 1:n:key, 2:func:count()Best, 1Best, 1Best, 1Best, 1`[1:], rt, true); err != nil {		t.Error(err)		return	}	if _, err := getResult("get Author traverse :::Song where (name beginswith 'A') or name beginswith 'L' end show key, name, 2:n:name", `Labels: Author Key, Author Name, NameFormat: auto, auto, autoData: 1:n:key, 1:n:name, 2:n:name000, John, Aria1000, John, Aria2000, John, Aria3000, John, Aria4123, Mike, LoveSong3`[1:], rt, true); err != nil {		t.Error(err)		return	}	// Make sure for the source of the count in row 2 (John, 4) is:	// q:lookup Author "000" traverse :::Song where name beginswith A or name beginswith L end show 2:n:key, 2:n:kind, 2:n:name	if res, err := getResult("get Author show name, @count(1, :::Song, r\"(name beginswith A) or name beginswith 'L' TRAVERSE ::: END\") AS mycount format xxx", `Labels: Author Name, mycountFormat: auto, xxxData: 1:n:name, 1:func:count()Hans, 0John, 4Mike, 1`[1:], rt, true); err != nil || res.RowSource(1)[1] != `q:lookup Author "000" traverse :::Song where name beginswith A or name beginswith L end show 2:n:key, 2:n:kind, 2:n:name` {		t.Error(res.RowSource(1)[1], err)		return	}	// Make sure the source query has the expected result (the source nodes for the count of 4)	if _, err := getResult(`lookup Author "000" traverse :::Song where name beginswith A or name beginswith L end show 2:n:key, 2:n:kind, 2:n:name`, `Labels: Key, Kind, NameFormat: auto, auto, autoData: 2:n:key, 2:n:kind, 2:n:nameAria1, Song, Aria1Aria2, Song, Aria2Aria3, Song, Aria3Aria4, Song, Aria4`[1:], rt2, true); err != nil {		t.Error(err)		return	}	// Use the count feature in the where clause - get all authors who have only one song beginning with M or L	if _, err := getResult("get Author where @count(:::Song, \"(name beginswith 'M') or name beginswith 'L'\") = 1 show key, name, @count(1, :::Song, \"(name beginswith 'M') or name beginswith 'L'\")", `Labels: Author Key, Author Name, CountFormat: auto, auto, autoData: 1:n:key, 1:n:name, 1:func:count()123, Mike, 1456, Hans, 1`[1:], rt, true); err != nil {		t.Error(err)		return	}}func TestFunctionErrors(t *testing.T) {	gm, _ := songGraphGroups()	rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))	// Test parsing and runtime error	if _, err := getResult("get group show key, @unknownfunction(:::Author)", "", rt, true); err.Error() !=		"EQL error in test: Invalid construct (Unknown function: unknownfunction) (Line:1 Pos:21)" {		t.Error(err)		return	}	if _, err := getResult("get group show key, @count(:::Author)", "", rt, true); err.Error() !=		"EQL error in test: Invalid construct (Count function requires 2 or 3 parameters: traversal step, traversal spec, condition clause) (Line:1 Pos:21)" {		t.Error(err)		return	}	if _, err := getResult("get group show key, @count(1, ::Author)", "", rt, true); err.Error() !=		"GraphError: Invalid data (Invalid spec: ::Author)" {		t.Error(err)		return	}	if _, err := getResult("get group show key, @count(99, ::Author)", "", rt, true); err.Error() !=		"EQL error in test: Invalid column data spec (Data index out of range: 99) (Line:1 Pos:21)" {		t.Error(err)		return	}	if _, err := getResult("get Author where @count(:::Song) > 3 show name, @count(1, :::Song)", `Labels: Author Name, CountFormat: auto, autoData: 1:n:name, 1:func:count()John, 4Mike, 4`[1:], rt, true); err != nil {		t.Error(err)		return	}	// Test parsing and runtime error	if _, err := getResult("get Author where @unknownfunction() > 3", "", rt, true); err.Error() !=		"EQL error in test: Invalid construct (Unknown function: unknownfunction) (Line:1 Pos:18)" {		t.Error(err)		return	}	if _, err := getResult("get Author where @count() > 3", "", rt, true); err.Error() !=		"EQL error in test: Invalid construct (Count function requires 1 or 2 parameters: traversal spec, condition clause) (Line:1 Pos:18)" {		t.Error(err)		return	}	if _, err := getResult("get Author where @count(::Song) > 3", "", rt, true); err.Error() !=		"GraphError: Invalid data (Invalid spec: ::Song)" {		t.Error(err)		return	}	if _, err := getResult("get Author show @objget(1)", "", rt, true); err.Error() !=		"EQL error in test: Invalid construct (Objget function requires 3 parameters: traversal step, attribute name, path to value) (Line:1 Pos:17)" {		t.Error(err)		return	}	if _, err := getResult("get Author where @parseDate()", "", rt, true); err.Error() !=		"EQL error in test: Invalid construct (parseDate function requires 1 parameter: date string) (Line:1 Pos:18)" {		t.Error(err)		return	}	if _, err := getResult("get Author where @count(:::Song, \"name\")", "", rt, true); err == nil || err.Error() !=		"EQL error in test: Invalid construct (Could not evaluate condition clause in count function) (Line:1 Pos:18)" {		t.Error(err)		return	}	if _, err := getResult("get Author where @count(:::Song, \"name =\")", "", rt, true); err == nil || err.Error() !=		"EQL error in test: Invalid construct (Invalid condition clause in count function: Parse error in count condition: Unexpected end) (Line:1 Pos:18)" {		t.Error(err)		return	}	if _, err := getResult("get Author where @count(:::Song, \"show\") = 1", "", rt, true); err == nil || err.Error() !=		"EQL error in test: Invalid construct (Invalid condition clause in count function: EQL error in test: Invalid construct (show) (Line:1 Pos:13)) (Line:1 Pos:18)" {		t.Error(err)		return	}	if _, err := getResult("get Author show @count(1, :::Song, \"name\")", "", rt, true); err == nil || err.Error() !=		"EQL error in test: Invalid construct (Could not evaluate condition clause in count function) (Line:1 Pos:17)" {		t.Error(err)		return	}	if _, err := getResult("get Author show @count(1, :::Song, \"name =\")", "", rt, true); err == nil || err.Error() !=		"EQL error in test: Invalid construct (Invalid condition clause in count function: Parse error in count condition: Unexpected end) (Line:1 Pos:17)" {		t.Error(err)		return	}	if _, err := getResult("get Author show @count(1, :::Song, \"show\")", "", rt, true); err == nil || err.Error() !=		"EQL error in test: Invalid construct (show) (Line:1 Pos:13)" {		t.Error(err)		return	}}
 |