prettyprinter_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package parser
  11. import (
  12. "fmt"
  13. "testing"
  14. )
  15. func TestSimpleExpressionPrinting(t *testing.T) {
  16. input := "a + b * 5 /2-1"
  17. expectedOutput := `
  18. minus
  19. plus
  20. value: "a"
  21. div
  22. times
  23. value: "b"
  24. value: "5"
  25. value: "2"
  26. value: "1"
  27. `[1:]
  28. if err := testPrettyPrinting(input, expectedOutput,
  29. "a + b * 5 / 2 - 1"); err != nil {
  30. t.Error(err)
  31. return
  32. }
  33. input = "(a + 1) * 5 / (6 - 2)"
  34. expectedOutput = `
  35. div
  36. times
  37. plus
  38. value: "a"
  39. value: "1"
  40. value: "5"
  41. minus
  42. value: "6"
  43. value: "2"
  44. `[1:]
  45. if err := testPrettyPrinting(input, expectedOutput,
  46. "(a + 1) * 5 / (6 - 2)"); err != nil {
  47. t.Error(err)
  48. return
  49. }
  50. input = "a + (1 * 5) / 6 - 2"
  51. expectedOutput = `
  52. minus
  53. plus
  54. value: "a"
  55. div
  56. times
  57. value: "1"
  58. value: "5"
  59. value: "6"
  60. value: "2"
  61. `[1:]
  62. if err := testPrettyPrinting(input, expectedOutput,
  63. "a + 1 * 5 / 6 - 2"); err != nil {
  64. t.Error(err)
  65. return
  66. }
  67. input = "a + 1 * [1,2,[1,2],3]"
  68. expectedOutput = `
  69. plus
  70. value: "a"
  71. times
  72. value: "1"
  73. list
  74. value: "1"
  75. value: "2"
  76. list
  77. value: "1"
  78. value: "2"
  79. value: "3"
  80. `[1:]
  81. if err := testPrettyPrinting(input, expectedOutput,
  82. "a + 1 * [1, 2, [1, 2], 3]"); err != nil {
  83. t.Error(err)
  84. return
  85. }
  86. input = "not (a + 1) * 5 and tRue or not 1 - 5 != !test"
  87. expectedOutput = `
  88. or
  89. and
  90. not
  91. times
  92. plus
  93. value: "a"
  94. value: "1"
  95. value: "5"
  96. true
  97. not
  98. !=
  99. minus
  100. value: "1"
  101. value: "5"
  102. value: "!test"
  103. `[1:]
  104. if err := testPrettyPrinting(input, expectedOutput,
  105. "not (a + 1) * 5 and true or not 1 - 5 != \"!test\""); err != nil {
  106. t.Error(err)
  107. return
  108. }
  109. input = "a and (b or c)"
  110. expectedOutput = `
  111. and
  112. value: "a"
  113. or
  114. value: "b"
  115. value: "c"
  116. `[1:]
  117. if err := testPrettyPrinting(input, expectedOutput,
  118. "a and (b or c)"); err != nil {
  119. t.Error(err)
  120. return
  121. }
  122. }
  123. func TestQueryPrinting(t *testing.T) {
  124. input := `
  125. GeT Song FROM group test`
  126. expectedOutput := `
  127. get
  128. value: "Song"
  129. from
  130. group
  131. value: "test"
  132. `[1:]
  133. if err := testPrettyPrinting(input, expectedOutput,
  134. "get Song from group test"); err != nil {
  135. t.Error(err)
  136. return
  137. }
  138. input = `
  139. GeT Song`
  140. expectedOutput = `
  141. get
  142. value: "Song"
  143. `[1:]
  144. if err := testPrettyPrinting(input, expectedOutput,
  145. "get Song"); err != nil {
  146. t.Error(err)
  147. return
  148. }
  149. input = `
  150. GeT Song where foo in bar and bar notin foo or xx = ""`
  151. expectedOutput = `
  152. get
  153. value: "Song"
  154. where
  155. or
  156. and
  157. in
  158. value: "foo"
  159. value: "bar"
  160. notin
  161. value: "bar"
  162. value: "foo"
  163. =
  164. value: "xx"
  165. value: ""
  166. `[1:]
  167. if err := testPrettyPrinting(input, expectedOutput,
  168. "get Song where foo in bar and bar notin foo or xx = \"\""); err != nil {
  169. t.Error(err)
  170. return
  171. }
  172. input = `
  173. lOOkup Song "a","b","c"`
  174. expectedOutput = `
  175. lookup
  176. value: "Song"
  177. value: "a"
  178. value: "b"
  179. value: "c"
  180. `[1:]
  181. if err := testPrettyPrinting(input, expectedOutput,
  182. `lookup Song "a", "b", "c"`); err != nil {
  183. t.Error(err)
  184. return
  185. }
  186. input = `
  187. lOOkup Song "a","b","c", "blaД" primary Song
  188. FROM group test
  189. show a, b`
  190. expectedOutput = `
  191. lookup
  192. value: "Song"
  193. value: "a"
  194. value: "b"
  195. value: "c"
  196. value: "blaД"
  197. primary
  198. value: "Song"
  199. from
  200. group
  201. value: "test"
  202. show
  203. showterm: "a"
  204. showterm: "b"
  205. `[1:]
  206. if err := testPrettyPrinting(input, expectedOutput,
  207. `lookup Song "a", "b", "c", "blaД" primary Song from group test
  208. show
  209. a,
  210. b`); err != nil {
  211. t.Error(err)
  212. return
  213. }
  214. input = `
  215. GeT bla FROM group test where attr:Name != val:Node1 AND b = 1 + -1 - 1 where True`
  216. expectedOutput = `
  217. get
  218. value: "bla"
  219. from
  220. group
  221. value: "test"
  222. where
  223. and
  224. !=
  225. value: "attr:Name"
  226. value: "val:Node1"
  227. =
  228. value: "b"
  229. minus
  230. plus
  231. value: "1"
  232. minus
  233. value: "1"
  234. value: "1"
  235. where
  236. true
  237. `[1:]
  238. if err := testPrettyPrinting(input, expectedOutput,
  239. `get bla from group test where attr:Name != val:Node1 and b = 1 + -1 - 1 where true`); err != nil {
  240. t.Error(err)
  241. return
  242. }
  243. input = `
  244. GeT bla TraverSE :::bla where true or false TraverSE test:::xxx where false end TraverSE :::ttt where true END END where n.ab = 1`
  245. expectedOutput = `
  246. get
  247. value: "bla"
  248. traverse
  249. value: ":::bla"
  250. where
  251. or
  252. true
  253. false
  254. traverse
  255. value: "test:::xxx"
  256. where
  257. false
  258. traverse
  259. value: ":::ttt"
  260. where
  261. true
  262. where
  263. =
  264. value: "n.ab"
  265. value: "1"
  266. `[1:]
  267. if err := testPrettyPrinting(input, expectedOutput, `
  268. get bla
  269. traverse :::bla where true or false
  270. traverse test:::xxx where false
  271. end
  272. traverse :::ttt where true
  273. end
  274. end where n.ab = 1`[1:]); err != nil {
  275. t.Error(err)
  276. return
  277. }
  278. input = `
  279. GeT Song where @a() or @count("File:File:StoredData:Data") > 1 and @boolfunc1(123,"test", aaa)`
  280. expectedOutput = `
  281. get
  282. value: "Song"
  283. where
  284. or
  285. func
  286. value: "a"
  287. and
  288. >
  289. func
  290. value: "count"
  291. value: "File:File:"...
  292. value: "1"
  293. func
  294. value: "boolfunc1"
  295. value: "123"
  296. value: "test"
  297. value: "aaa"
  298. `[1:]
  299. if err := testPrettyPrinting(input, expectedOutput,
  300. `get Song where @a() or @count(File:File:StoredData:Data) > 1 and @boolfunc1(123, test, aaa)`); err != nil {
  301. t.Error(err)
  302. return
  303. }
  304. }
  305. func TestShowPrinting(t *testing.T) {
  306. input := `
  307. get song where true primary 1:song show name, state`
  308. expectedOutput := `
  309. get
  310. value: "song"
  311. where
  312. true
  313. primary
  314. value: "1:song"
  315. show
  316. showterm: "name"
  317. showterm: "state"
  318. `[1:]
  319. if err := testPrettyPrinting(input, expectedOutput, `
  320. get song where true primary 1:song
  321. show
  322. name,
  323. state`[1:]); err != nil {
  324. t.Error(err)
  325. return
  326. }
  327. input = `
  328. get song where true primary 1:song show name, state, @test(12, r"34") AS Bla FORMAT x, key`
  329. expectedOutput = `
  330. get
  331. value: "song"
  332. where
  333. true
  334. primary
  335. value: "1:song"
  336. show
  337. showterm: "name"
  338. showterm: "state"
  339. showterm
  340. func
  341. value: "test"
  342. value: "12"
  343. value: "34"
  344. as
  345. value: "Bla"
  346. format
  347. value: "x"
  348. showterm: "key"
  349. `[1:]
  350. if err := testPrettyPrinting(input, expectedOutput, `
  351. get song where true primary 1:song
  352. show
  353. name,
  354. state,
  355. @test(12, 34) as Bla format x,
  356. key`[1:]); err != nil {
  357. t.Error(err)
  358. return
  359. }
  360. input = `
  361. get song where true primary 1:song show @test(12, r"34") format x`
  362. expectedOutput = `
  363. get
  364. value: "song"
  365. where
  366. true
  367. primary
  368. value: "1:song"
  369. show
  370. showterm
  371. func
  372. value: "test"
  373. value: "12"
  374. value: "34"
  375. format
  376. value: "x"
  377. `[1:]
  378. if err := testPrettyPrinting(input, expectedOutput, `
  379. get song where true primary 1:song
  380. show
  381. @test(12, 34) format x`[1:]); err != nil {
  382. t.Error(err)
  383. return
  384. }
  385. input = `
  386. get song where true primary 1:song show
  387. Song:title AS r'Title (mytitle)',
  388. r'Song!2:t title' AS "Title test" FORMAT text:bla_bla_blub:dudududu,
  389. x:kind`
  390. expectedOutput = `
  391. get
  392. value: "song"
  393. where
  394. true
  395. primary
  396. value: "1:song"
  397. show
  398. showterm: "Song:title"
  399. as
  400. value: "Title (myt"...
  401. showterm: "Song!2:t t"...
  402. as
  403. value: "Title test"
  404. format
  405. value: "text:bla_b"...
  406. showterm: "x:kind"
  407. `[1:]
  408. if err := testPrettyPrinting(input, expectedOutput, `
  409. get song where true primary 1:song
  410. show
  411. Song:title as "Title (mytitle)",
  412. "Song!2:t title" as "Title test" format text:bla_bla_blub:dudududu,
  413. x:kind`[1:]); err != nil {
  414. t.Error(err)
  415. return
  416. }
  417. input = `
  418. get song where true // 'div' show bla wIth orderinG(ASCending aa,Descending bb), FILTERING(ISNOTNULL test2,UNIQUE test3, uniquecount test3), nulltraversal(true)`
  419. expectedOutput = `
  420. get
  421. value: "song"
  422. where
  423. divint
  424. true
  425. value: "div"
  426. show
  427. showterm: "bla"
  428. with
  429. ordering
  430. asc
  431. value: "aa"
  432. desc
  433. value: "bb"
  434. filtering
  435. isnotnull
  436. value: "test2"
  437. unique
  438. value: "test3"
  439. uniquecount
  440. value: "test3"
  441. nulltraversal
  442. true
  443. `[1:]
  444. if err := testPrettyPrinting(input, expectedOutput, `
  445. get song where true // div
  446. show
  447. bla
  448. with
  449. ordering(ascending aa, descending bb),
  450. filtering(isnotnull test2, unique test3, uniquecount test3),
  451. nulltraversal(true)`[1:]); err != nil {
  452. t.Error(err)
  453. return
  454. }
  455. }
  456. func TestSpecialCases(t *testing.T) {
  457. // Test error reporting of an illegal AST node
  458. input := "get test"
  459. astres, err := ParseWithRuntime("mytest", input, &TestRuntimeProvider{})
  460. if err != nil {
  461. t.Error(err)
  462. return
  463. }
  464. // Create an illegal node
  465. astres.Children[0].Name = "foobar"
  466. _, err = PrettyPrint(astres)
  467. if err.Error() != "Could not find template for foobar (tempkey: foobar)" {
  468. t.Error("Unexpected result:", err)
  469. return
  470. }
  471. // Test if a value contains a double quote
  472. input = `get test where a = 'test "'`
  473. astres, err = ParseWithRuntime("mytest", input, &TestRuntimeProvider{})
  474. if err != nil {
  475. t.Error(err)
  476. return
  477. }
  478. ppres, err := PrettyPrint(astres)
  479. if ppres != `get test where a = 'test "'` {
  480. t.Error("Unexpected result:", ppres)
  481. return
  482. }
  483. // Test if value contains double and single quote
  484. input = `get test where a = "test 1: \" 2: ' "`
  485. astres, err = ParseWithRuntime("mytest", input, nil)
  486. if err != nil {
  487. t.Error(err)
  488. return
  489. }
  490. ppres, err = PrettyPrint(astres)
  491. if ppres != `get test where a = "test 1: \" 2: ' "` {
  492. t.Error("Unexpected result:", ppres)
  493. return
  494. }
  495. }
  496. func testPrettyPrinting(input, astOutput, ppOutput string) error {
  497. astres, err := ParseWithRuntime("mytest", input, &TestRuntimeProvider{})
  498. if err != nil || fmt.Sprint(astres) != astOutput {
  499. return fmt.Errorf("Unexpected parser output:\n%v expected was:\n%v Error: %v", astres, astOutput, err)
  500. }
  501. ppres, err := PrettyPrint(astres)
  502. if err != nil || ppres != ppOutput {
  503. return fmt.Errorf("Unexpected result: %v %v", ppres, err)
  504. }
  505. // Make sure the pretty printed result is valid and gets the same parse tree
  506. astres2, err := ParseWithRuntime("mytest", ppres, &TestRuntimeProvider{})
  507. if err != nil || fmt.Sprint(astres2) != astOutput {
  508. return fmt.Errorf("Unexpected parser output from pretty print string:\n%v expected was:\n%v Error: %v", astres2, astOutput, err)
  509. }
  510. return nil
  511. }