marshal_test.go 15 KB

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