| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578 | /* * 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 parserimport (	"fmt"	"testing")func TestSimpleExpressionPrinting(t *testing.T) {	input := "a + b * 5 /2-1"	expectedOutput := `minus  plus    value: "a"    div      times        value: "b"        value: "5"      value: "2"  value: "1"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		"a + b * 5 / 2 - 1"); err != nil {		t.Error(err)		return	}	input = "(a + 1) * 5 / (6 - 2)"	expectedOutput = `div  times    plus      value: "a"      value: "1"    value: "5"  minus    value: "6"    value: "2"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		"(a + 1) * 5 / (6 - 2)"); err != nil {		t.Error(err)		return	}	input = "a + (1 * 5) / 6 - 2"	expectedOutput = `minus  plus    value: "a"    div      times        value: "1"        value: "5"      value: "6"  value: "2"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		"a + 1 * 5 / 6 - 2"); err != nil {		t.Error(err)		return	}	input = "a + 1 * [1,2,[1,2],3]"	expectedOutput = `plus  value: "a"  times    value: "1"    list      value: "1"      value: "2"      list        value: "1"        value: "2"      value: "3"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		"a + 1 * [1, 2, [1, 2], 3]"); err != nil {		t.Error(err)		return	}	input = "not (a + 1) * 5 and tRue or not 1 - 5 != !test"	expectedOutput = `or  and    not      times        plus          value: "a"          value: "1"        value: "5"    true  not    !=      minus        value: "1"        value: "5"      value: "!test"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		"not (a + 1) * 5 and true or not 1 - 5 != \"!test\""); err != nil {		t.Error(err)		return	}	input = "a and (b or c)"	expectedOutput = `and  value: "a"  or    value: "b"    value: "c"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		"a and (b or c)"); err != nil {		t.Error(err)		return	}}func TestQueryPrinting(t *testing.T) {	input := `GeT Song FROM group test`	expectedOutput := `get  value: "Song"  from    group      value: "test"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		"get Song from group test"); err != nil {		t.Error(err)		return	}	input = `GeT Song`	expectedOutput = `get  value: "Song"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		"get Song"); err != nil {		t.Error(err)		return	}	input = `GeT Song where foo in bar and bar notin foo or xx = ""`	expectedOutput = `get  value: "Song"  where    or      and        in          value: "foo"          value: "bar"        notin          value: "bar"          value: "foo"      =        value: "xx"        value: ""`[1:]	if err := testPrettyPrinting(input, expectedOutput,		"get Song where foo in bar and bar notin foo or xx = \"\""); err != nil {		t.Error(err)		return	}	input = `lOOkup Song "a","b","c"`	expectedOutput = `lookup  value: "Song"  value: "a"  value: "b"  value: "c"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		`lookup Song "a", "b", "c"`); err != nil {		t.Error(err)		return	}	input = `lOOkup Song "a","b","c", "blaД" primary SongFROM group testshow a, b`	expectedOutput = `lookup  value: "Song"  value: "a"  value: "b"  value: "c"  value: "blaД"  primary    value: "Song"  from    group      value: "test"  show    showterm: "a"    showterm: "b"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		`lookup Song "a", "b", "c", "blaД" primary Song from group testshow  a,  b`); err != nil {		t.Error(err)		return	}	input = `GeT bla FROM group test where attr:Name != val:Node1 AND b = 1 + -1 - 1 where True`	expectedOutput = `get  value: "bla"  from    group      value: "test"  where    and      !=        value: "attr:Name"        value: "val:Node1"      =        value: "b"        minus          plus            value: "1"            minus              value: "1"          value: "1"  where    true`[1:]	if err := testPrettyPrinting(input, expectedOutput,		`get bla from group test where attr:Name != val:Node1 and b = 1 + -1 - 1 where true`); err != nil {		t.Error(err)		return	}	input = `GeT bla TraverSE :::bla where true or false TraverSE test:::xxx where false end TraverSE :::ttt where true END END where n.ab = 1`	expectedOutput = `get  value: "bla"  traverse    value: ":::bla"    where      or        true        false    traverse      value: "test:::xxx"      where        false    traverse      value: ":::ttt"      where        true  where    =      value: "n.ab"      value: "1"`[1:]	if err := testPrettyPrinting(input, expectedOutput, `get bla   traverse :::bla where true or false     traverse test:::xxx where false    end     traverse :::ttt where true    end  end where n.ab = 1`[1:]); err != nil {		t.Error(err)		return	}	input = `GeT Song where @a() or @count("File:File:StoredData:Data") > 1 and @boolfunc1(123,"test", aaa)`	expectedOutput = `get  value: "Song"  where    or      func        value: "a"      and        >          func            value: "count"            value: "File:File:"...          value: "1"        func          value: "boolfunc1"          value: "123"          value: "test"          value: "aaa"`[1:]	if err := testPrettyPrinting(input, expectedOutput,		`get Song where @a() or @count(File:File:StoredData:Data) > 1 and @boolfunc1(123, test, aaa)`); err != nil {		t.Error(err)		return	}}func TestShowPrinting(t *testing.T) {	input := `get song where true primary 1:song show name, state`	expectedOutput := `get  value: "song"  where    true  primary    value: "1:song"  show    showterm: "name"    showterm: "state"`[1:]	if err := testPrettyPrinting(input, expectedOutput, `get song where true primary 1:songshow  name,  state`[1:]); err != nil {		t.Error(err)		return	}	input = `get song where true primary 1:song show name, state, @test(12, r"34") AS Bla FORMAT x, key`	expectedOutput = `get  value: "song"  where    true  primary    value: "1:song"  show    showterm: "name"    showterm: "state"    showterm      func        value: "test"        value: "12"        value: "34"      as        value: "Bla"      format        value: "x"    showterm: "key"`[1:]	if err := testPrettyPrinting(input, expectedOutput, `get song where true primary 1:songshow  name,  state,  @test(12, 34) as Bla format x,  key`[1:]); err != nil {		t.Error(err)		return	}	input = `get song where true primary 1:song show @test(12, r"34") format x`	expectedOutput = `get  value: "song"  where    true  primary    value: "1:song"  show    showterm      func        value: "test"        value: "12"        value: "34"      format        value: "x"`[1:]	if err := testPrettyPrinting(input, expectedOutput, `get song where true primary 1:songshow  @test(12, 34) format x`[1:]); err != nil {		t.Error(err)		return	}	input = `get song where true primary 1:song show Song:title AS r'Title (mytitle)',r'Song!2:t title' AS "Title test" FORMAT text:bla_bla_blub:dudududu,x:kind`	expectedOutput = `get  value: "song"  where    true  primary    value: "1:song"  show    showterm: "Song:title"      as        value: "Title (myt"...    showterm: "Song!2:t t"...      as        value: "Title test"      format        value: "text:bla_b"...    showterm: "x:kind"`[1:]	if err := testPrettyPrinting(input, expectedOutput, `get song where true primary 1:songshow  Song:title as "Title (mytitle)",  "Song!2:t title" as "Title test" format text:bla_bla_blub:dudududu,  x:kind`[1:]); err != nil {		t.Error(err)		return	}	input = `get song where true // 'div' show bla wIth orderinG(ASCending aa,Descending bb), FILTERING(ISNOTNULL test2,UNIQUE test3, uniquecount test3), nulltraversal(true)`	expectedOutput = `get  value: "song"  where    divint      true      value: "div"  show    showterm: "bla"  with    ordering      asc        value: "aa"      desc        value: "bb"    filtering      isnotnull        value: "test2"      unique        value: "test3"      uniquecount        value: "test3"    nulltraversal      true`[1:]	if err := testPrettyPrinting(input, expectedOutput, `get song where true // divshow  bla with  ordering(ascending aa, descending bb),  filtering(isnotnull test2, unique test3, uniquecount test3),  nulltraversal(true)`[1:]); err != nil {		t.Error(err)		return	}}func TestSpecialCases(t *testing.T) {	// Test error reporting of an illegal AST node	input := "get test"	astres, err := ParseWithRuntime("mytest", input, &TestRuntimeProvider{})	if err != nil {		t.Error(err)		return	}	// Create an illegal node	astres.Children[0].Name = "foobar"	_, err = PrettyPrint(astres)	if err.Error() != "Could not find template for foobar (tempkey: foobar)" {		t.Error("Unexpected result:", err)		return	}	// Test if a value contains a double quote	input = `get test where a = 'test "'`	astres, err = ParseWithRuntime("mytest", input, &TestRuntimeProvider{})	if err != nil {		t.Error(err)		return	}	ppres, err := PrettyPrint(astres)	if ppres != `get test where a = 'test "'` {		t.Error("Unexpected result:", ppres)		return	}	// Test if value contains double and single quote	input = `get test where a = "test 1: \" 2: ' "`	astres, err = ParseWithRuntime("mytest", input, nil)	if err != nil {		t.Error(err)		return	}	ppres, err = PrettyPrint(astres)	if ppres != `get test where a = "test 1: \" 2: ' "` {		t.Error("Unexpected result:", ppres)		return	}}func testPrettyPrinting(input, astOutput, ppOutput string) error {	astres, err := ParseWithRuntime("mytest", input, &TestRuntimeProvider{})	if err != nil || fmt.Sprint(astres) != astOutput {		return fmt.Errorf("Unexpected parser output:\n%v expected was:\n%v Error: %v", astres, astOutput, err)	}	ppres, err := PrettyPrint(astres)	if err != nil || ppres != ppOutput {		return fmt.Errorf("Unexpected result: %v %v", ppres, err)	}	// Make sure the pretty printed result is valid and gets the same parse tree	astres2, err := ParseWithRuntime("mytest", ppres, &TestRuntimeProvider{})	if err != nil || fmt.Sprint(astres2) != astOutput {		return fmt.Errorf("Unexpected parser output from pretty print string:\n%v expected was:\n%v Error: %v", astres2, astOutput, err)	}	return nil}
 |