marshal_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. package parser
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "os"
  7. "reflect"
  8. "strings"
  9. "testing"
  10. "github.com/dop251/goja/ast"
  11. )
  12. func marshal(name string, children ...interface{}) interface{} {
  13. if len(children) == 1 {
  14. if name == "" {
  15. return testMarshalNode(children[0])
  16. }
  17. return map[string]interface{}{
  18. name: children[0],
  19. }
  20. }
  21. map_ := map[string]interface{}{}
  22. length := len(children) / 2
  23. for i := 0; i < length; i++ {
  24. name := children[i*2].(string)
  25. value := children[i*2+1]
  26. map_[name] = value
  27. }
  28. if name == "" {
  29. return map_
  30. }
  31. return map[string]interface{}{
  32. name: map_,
  33. }
  34. }
  35. func testMarshalNode(node interface{}) interface{} {
  36. switch node := node.(type) {
  37. // Expression
  38. case *ast.ArrayLiteral:
  39. return marshal("Array", testMarshalNode(node.Value))
  40. case *ast.AssignExpression:
  41. return marshal("Assign",
  42. "Left", testMarshalNode(node.Left),
  43. "Right", testMarshalNode(node.Right),
  44. )
  45. case *ast.BinaryExpression:
  46. return marshal("BinaryExpression",
  47. "Operator", node.Operator.String(),
  48. "Left", testMarshalNode(node.Left),
  49. "Right", testMarshalNode(node.Right),
  50. )
  51. case *ast.BooleanLiteral:
  52. return marshal("Literal", node.Value)
  53. case *ast.CallExpression:
  54. return marshal("Call",
  55. "Callee", testMarshalNode(node.Callee),
  56. "ArgumentList", testMarshalNode(node.ArgumentList),
  57. )
  58. case *ast.ConditionalExpression:
  59. return marshal("Conditional",
  60. "Test", testMarshalNode(node.Test),
  61. "Consequent", testMarshalNode(node.Consequent),
  62. "Alternate", testMarshalNode(node.Alternate),
  63. )
  64. case *ast.DotExpression:
  65. return marshal("Dot",
  66. "Left", testMarshalNode(node.Left),
  67. "Member", node.Identifier.Name,
  68. )
  69. case *ast.NewExpression:
  70. return marshal("New",
  71. "Callee", testMarshalNode(node.Callee),
  72. "ArgumentList", testMarshalNode(node.ArgumentList),
  73. )
  74. case *ast.NullLiteral:
  75. return marshal("Literal", nil)
  76. case *ast.NumberLiteral:
  77. return marshal("Literal", node.Value)
  78. case *ast.ObjectLiteral:
  79. return marshal("Object", testMarshalNode(node.Value))
  80. case *ast.RegExpLiteral:
  81. return marshal("Literal", node.Literal)
  82. case *ast.StringLiteral:
  83. return marshal("Literal", node.Literal)
  84. case *ast.VariableExpression:
  85. return []interface{}{node.Name, testMarshalNode(node.Initializer)}
  86. // Statement
  87. case *ast.Program:
  88. return testMarshalNode(node.Body)
  89. case *ast.BlockStatement:
  90. return marshal("BlockStatement", testMarshalNode(node.List))
  91. case *ast.EmptyStatement:
  92. return "EmptyStatement"
  93. case *ast.ExpressionStatement:
  94. return testMarshalNode(node.Expression)
  95. case *ast.ForInStatement:
  96. return marshal("ForIn",
  97. "Into", marshal("", node.Into),
  98. "Source", marshal("", node.Source),
  99. "Body", marshal("", node.Body),
  100. )
  101. case *ast.FunctionLiteral:
  102. return marshal("Function", testMarshalNode(node.Body))
  103. case *ast.Identifier:
  104. return marshal("Identifier", node.Name)
  105. case *ast.IfStatement:
  106. if_ := marshal("",
  107. "Test", testMarshalNode(node.Test),
  108. "Consequent", testMarshalNode(node.Consequent),
  109. ).(map[string]interface{})
  110. if node.Alternate != nil {
  111. if_["Alternate"] = testMarshalNode(node.Alternate)
  112. }
  113. return marshal("If", if_)
  114. case *ast.LabelledStatement:
  115. return marshal("Label",
  116. "Name", node.Label.Name,
  117. "Statement", testMarshalNode(node.Statement),
  118. )
  119. case ast.Property:
  120. return marshal("",
  121. "Key", node.Key,
  122. "Value", testMarshalNode(node.Value),
  123. )
  124. case *ast.ReturnStatement:
  125. return marshal("Return", testMarshalNode(node.Argument))
  126. case *ast.SequenceExpression:
  127. return marshal("Sequence", testMarshalNode(node.Sequence))
  128. case *ast.ThrowStatement:
  129. return marshal("Throw", testMarshalNode(node.Argument))
  130. case *ast.VariableStatement:
  131. return marshal("Var", testMarshalNode(node.List))
  132. }
  133. {
  134. value := reflect.ValueOf(node)
  135. if value.Kind() == reflect.Slice {
  136. tmp0 := []interface{}{}
  137. for index := 0; index < value.Len(); index++ {
  138. tmp0 = append(tmp0, testMarshalNode(value.Index(index).Interface()))
  139. }
  140. return tmp0
  141. }
  142. }
  143. if node != nil {
  144. fmt.Fprintf(os.Stderr, "testMarshalNode(%T)\n", node)
  145. }
  146. return nil
  147. }
  148. func testMarshal(node interface{}) string {
  149. value, err := json.Marshal(testMarshalNode(node))
  150. if err != nil {
  151. panic(err)
  152. }
  153. return string(value)
  154. }
  155. func TestParserAST(t *testing.T) {
  156. tt(t, func() {
  157. test := func(inputOutput string) {
  158. match := matchBeforeAfterSeparator.FindStringIndex(inputOutput)
  159. input := strings.TrimSpace(inputOutput[0:match[0]])
  160. wantOutput := strings.TrimSpace(inputOutput[match[1]:])
  161. _, program, err := testParse(input)
  162. is(err, nil)
  163. haveOutput := testMarshal(program)
  164. tmp0, tmp1 := bytes.Buffer{}, bytes.Buffer{}
  165. json.Indent(&tmp0, []byte(haveOutput), "\t\t", " ")
  166. json.Indent(&tmp1, []byte(wantOutput), "\t\t", " ")
  167. is("\n\t\t"+tmp0.String(), "\n\t\t"+tmp1.String())
  168. }
  169. test(`
  170. ---
  171. []
  172. `)
  173. test(`
  174. ;
  175. ---
  176. [
  177. "EmptyStatement"
  178. ]
  179. `)
  180. test(`
  181. ;;;
  182. ---
  183. [
  184. "EmptyStatement",
  185. "EmptyStatement",
  186. "EmptyStatement"
  187. ]
  188. `)
  189. test(`
  190. 1; true; abc; "abc"; null;
  191. ---
  192. [
  193. {
  194. "Literal": 1
  195. },
  196. {
  197. "Literal": true
  198. },
  199. {
  200. "Identifier": "abc"
  201. },
  202. {
  203. "Literal": "\"abc\""
  204. },
  205. {
  206. "Literal": null
  207. }
  208. ]
  209. `)
  210. test(`
  211. { 1; null; 3.14159; ; }
  212. ---
  213. [
  214. {
  215. "BlockStatement": [
  216. {
  217. "Literal": 1
  218. },
  219. {
  220. "Literal": null
  221. },
  222. {
  223. "Literal": 3.14159
  224. },
  225. "EmptyStatement"
  226. ]
  227. }
  228. ]
  229. `)
  230. test(`
  231. new abc();
  232. ---
  233. [
  234. {
  235. "New": {
  236. "ArgumentList": [],
  237. "Callee": {
  238. "Identifier": "abc"
  239. }
  240. }
  241. }
  242. ]
  243. `)
  244. test(`
  245. new abc(1, 3.14159)
  246. ---
  247. [
  248. {
  249. "New": {
  250. "ArgumentList": [
  251. {
  252. "Literal": 1
  253. },
  254. {
  255. "Literal": 3.14159
  256. }
  257. ],
  258. "Callee": {
  259. "Identifier": "abc"
  260. }
  261. }
  262. }
  263. ]
  264. `)
  265. test(`
  266. true ? false : true
  267. ---
  268. [
  269. {
  270. "Conditional": {
  271. "Alternate": {
  272. "Literal": true
  273. },
  274. "Consequent": {
  275. "Literal": false
  276. },
  277. "Test": {
  278. "Literal": true
  279. }
  280. }
  281. }
  282. ]
  283. `)
  284. test(`
  285. true || false
  286. ---
  287. [
  288. {
  289. "BinaryExpression": {
  290. "Left": {
  291. "Literal": true
  292. },
  293. "Operator": "||",
  294. "Right": {
  295. "Literal": false
  296. }
  297. }
  298. }
  299. ]
  300. `)
  301. test(`
  302. 0 + { abc: true }
  303. ---
  304. [
  305. {
  306. "BinaryExpression": {
  307. "Left": {
  308. "Literal": 0
  309. },
  310. "Operator": "+",
  311. "Right": {
  312. "Object": [
  313. {
  314. "Key": "abc",
  315. "Value": {
  316. "Literal": true
  317. }
  318. }
  319. ]
  320. }
  321. }
  322. }
  323. ]
  324. `)
  325. test(`
  326. 1 == "1"
  327. ---
  328. [
  329. {
  330. "BinaryExpression": {
  331. "Left": {
  332. "Literal": 1
  333. },
  334. "Operator": "==",
  335. "Right": {
  336. "Literal": "\"1\""
  337. }
  338. }
  339. }
  340. ]
  341. `)
  342. test(`
  343. abc(1)
  344. ---
  345. [
  346. {
  347. "Call": {
  348. "ArgumentList": [
  349. {
  350. "Literal": 1
  351. }
  352. ],
  353. "Callee": {
  354. "Identifier": "abc"
  355. }
  356. }
  357. }
  358. ]
  359. `)
  360. test(`
  361. Math.pow(3, 2)
  362. ---
  363. [
  364. {
  365. "Call": {
  366. "ArgumentList": [
  367. {
  368. "Literal": 3
  369. },
  370. {
  371. "Literal": 2
  372. }
  373. ],
  374. "Callee": {
  375. "Dot": {
  376. "Left": {
  377. "Identifier": "Math"
  378. },
  379. "Member": "pow"
  380. }
  381. }
  382. }
  383. }
  384. ]
  385. `)
  386. test(`
  387. 1, 2, 3
  388. ---
  389. [
  390. {
  391. "Sequence": [
  392. {
  393. "Literal": 1
  394. },
  395. {
  396. "Literal": 2
  397. },
  398. {
  399. "Literal": 3
  400. }
  401. ]
  402. }
  403. ]
  404. `)
  405. test(`
  406. / abc /gim;
  407. ---
  408. [
  409. {
  410. "Literal": "/ abc /gim"
  411. }
  412. ]
  413. `)
  414. test(`
  415. if (0)
  416. 1;
  417. ---
  418. [
  419. {
  420. "If": {
  421. "Consequent": {
  422. "Literal": 1
  423. },
  424. "Test": {
  425. "Literal": 0
  426. }
  427. }
  428. }
  429. ]
  430. `)
  431. test(`
  432. 0+function(){
  433. return;
  434. }
  435. ---
  436. [
  437. {
  438. "BinaryExpression": {
  439. "Left": {
  440. "Literal": 0
  441. },
  442. "Operator": "+",
  443. "Right": {
  444. "Function": {
  445. "BlockStatement": [
  446. {
  447. "Return": null
  448. }
  449. ]
  450. }
  451. }
  452. }
  453. }
  454. ]
  455. `)
  456. test(`
  457. xyzzy // Ignore it
  458. // Ignore this
  459. // And this
  460. /* And all..
  461. ... of this!
  462. */
  463. "Nothing happens."
  464. // And finally this
  465. ---
  466. [
  467. {
  468. "Identifier": "xyzzy"
  469. },
  470. {
  471. "Literal": "\"Nothing happens.\""
  472. }
  473. ]
  474. `)
  475. test(`
  476. ((x & (x = 1)) !== 0)
  477. ---
  478. [
  479. {
  480. "BinaryExpression": {
  481. "Left": {
  482. "BinaryExpression": {
  483. "Left": {
  484. "Identifier": "x"
  485. },
  486. "Operator": "\u0026",
  487. "Right": {
  488. "Assign": {
  489. "Left": {
  490. "Identifier": "x"
  491. },
  492. "Right": {
  493. "Literal": 1
  494. }
  495. }
  496. }
  497. }
  498. },
  499. "Operator": "!==",
  500. "Right": {
  501. "Literal": 0
  502. }
  503. }
  504. }
  505. ]
  506. `)
  507. test(`
  508. { abc: 'def' }
  509. ---
  510. [
  511. {
  512. "BlockStatement": [
  513. {
  514. "Label": {
  515. "Name": "abc",
  516. "Statement": {
  517. "Literal": "'def'"
  518. }
  519. }
  520. }
  521. ]
  522. }
  523. ]
  524. `)
  525. test(`
  526. // This is not an object, this is a string literal with a label!
  527. ({ abc: 'def' })
  528. ---
  529. [
  530. {
  531. "Object": [
  532. {
  533. "Key": "abc",
  534. "Value": {
  535. "Literal": "'def'"
  536. }
  537. }
  538. ]
  539. }
  540. ]
  541. `)
  542. test(`
  543. [,]
  544. ---
  545. [
  546. {
  547. "Array": [
  548. null
  549. ]
  550. }
  551. ]
  552. `)
  553. test(`
  554. [,,]
  555. ---
  556. [
  557. {
  558. "Array": [
  559. null,
  560. null
  561. ]
  562. }
  563. ]
  564. `)
  565. test(`
  566. ({ get abc() {} })
  567. ---
  568. [
  569. {
  570. "Object": [
  571. {
  572. "Key": "abc",
  573. "Value": {
  574. "Function": {
  575. "BlockStatement": []
  576. }
  577. }
  578. }
  579. ]
  580. }
  581. ]
  582. `)
  583. test(`
  584. /abc/.source
  585. ---
  586. [
  587. {
  588. "Dot": {
  589. "Left": {
  590. "Literal": "/abc/"
  591. },
  592. "Member": "source"
  593. }
  594. }
  595. ]
  596. `)
  597. test(`
  598. xyzzy
  599. throw new TypeError("Nothing happens.")
  600. ---
  601. [
  602. {
  603. "Identifier": "xyzzy"
  604. },
  605. {
  606. "Throw": {
  607. "New": {
  608. "ArgumentList": [
  609. {
  610. "Literal": "\"Nothing happens.\""
  611. }
  612. ],
  613. "Callee": {
  614. "Identifier": "TypeError"
  615. }
  616. }
  617. }
  618. }
  619. ]
  620. `)
  621. // When run, this will call a type error to be thrown
  622. // This is essentially the same as:
  623. //
  624. // var abc = 1(function(){})()
  625. //
  626. test(`
  627. var abc = 1
  628. (function(){
  629. })()
  630. ---
  631. [
  632. {
  633. "Var": [
  634. [
  635. "abc",
  636. {
  637. "Call": {
  638. "ArgumentList": [],
  639. "Callee": {
  640. "Call": {
  641. "ArgumentList": [
  642. {
  643. "Function": {
  644. "BlockStatement": []
  645. }
  646. }
  647. ],
  648. "Callee": {
  649. "Literal": 1
  650. }
  651. }
  652. }
  653. }
  654. }
  655. ]
  656. ]
  657. }
  658. ]
  659. `)
  660. test(`
  661. "use strict"
  662. ---
  663. [
  664. {
  665. "Literal": "\"use strict\""
  666. }
  667. ]
  668. `)
  669. test(`
  670. "use strict"
  671. abc = 1 + 2 + 11
  672. ---
  673. [
  674. {
  675. "Literal": "\"use strict\""
  676. },
  677. {
  678. "Assign": {
  679. "Left": {
  680. "Identifier": "abc"
  681. },
  682. "Right": {
  683. "BinaryExpression": {
  684. "Left": {
  685. "BinaryExpression": {
  686. "Left": {
  687. "Literal": 1
  688. },
  689. "Operator": "+",
  690. "Right": {
  691. "Literal": 2
  692. }
  693. }
  694. },
  695. "Operator": "+",
  696. "Right": {
  697. "Literal": 11
  698. }
  699. }
  700. }
  701. }
  702. }
  703. ]
  704. `)
  705. test(`
  706. abc = function() { 'use strict' }
  707. ---
  708. [
  709. {
  710. "Assign": {
  711. "Left": {
  712. "Identifier": "abc"
  713. },
  714. "Right": {
  715. "Function": {
  716. "BlockStatement": [
  717. {
  718. "Literal": "'use strict'"
  719. }
  720. ]
  721. }
  722. }
  723. }
  724. }
  725. ]
  726. `)
  727. test(`
  728. for (var abc in def) {
  729. }
  730. ---
  731. [
  732. {
  733. "ForIn": {
  734. "Body": {
  735. "BlockStatement": []
  736. },
  737. "Into": [
  738. "abc",
  739. null
  740. ],
  741. "Source": {
  742. "Identifier": "def"
  743. }
  744. }
  745. }
  746. ]
  747. `)
  748. test(`
  749. abc = {
  750. '"': "'",
  751. "'": '"',
  752. }
  753. ---
  754. [
  755. {
  756. "Assign": {
  757. "Left": {
  758. "Identifier": "abc"
  759. },
  760. "Right": {
  761. "Object": [
  762. {
  763. "Key": "\"",
  764. "Value": {
  765. "Literal": "\"'\""
  766. }
  767. },
  768. {
  769. "Key": "'",
  770. "Value": {
  771. "Literal": "'\"'"
  772. }
  773. }
  774. ]
  775. }
  776. }
  777. }
  778. ]
  779. `)
  780. return
  781. test(`
  782. if (!abc && abc.jkl(def) && abc[0] === +abc[0] && abc.length < ghi) {
  783. }
  784. ---
  785. [
  786. {
  787. "If": {
  788. "Consequent": {
  789. "BlockStatement": []
  790. },
  791. "Test": {
  792. "BinaryExpression": {
  793. "Left": {
  794. "BinaryExpression": {
  795. "Left": {
  796. "BinaryExpression": {
  797. "Left": null,
  798. "Operator": "\u0026\u0026",
  799. "Right": {
  800. "Call": {
  801. "ArgumentList": [
  802. {
  803. "Identifier": "def"
  804. }
  805. ],
  806. "Callee": {
  807. "Dot": {
  808. "Left": {
  809. "Identifier": "abc"
  810. },
  811. "Member": "jkl"
  812. }
  813. }
  814. }
  815. }
  816. }
  817. },
  818. "Operator": "\u0026\u0026",
  819. "Right": {
  820. "BinaryExpression": {
  821. "Left": null,
  822. "Operator": "===",
  823. "Right": null
  824. }
  825. }
  826. }
  827. },
  828. "Operator": "\u0026\u0026",
  829. "Right": {
  830. "BinaryExpression": {
  831. "Left": {
  832. "Dot": {
  833. "Left": {
  834. "Identifier": "abc"
  835. },
  836. "Member": "length"
  837. }
  838. },
  839. "Operator": "\u003c",
  840. "Right": {
  841. "Identifier": "ghi"
  842. }
  843. }
  844. }
  845. }
  846. }
  847. }
  848. }
  849. ]
  850. `)
  851. })
  852. }