language-javascript-0.7.1.0: test/Test/Language/Javascript/RoundTrip.hs
module Test.Language.Javascript.RoundTrip
( testRoundTrip
) where
import Test.Hspec
import Language.JavaScript.Parser
import qualified Language.JavaScript.Parser.AST as AST
testRoundTrip :: Spec
testRoundTrip = describe "Roundtrip:" $ do
it "multi comment" $ do
testRT "/*a*/\n//foo\nnull"
testRT "/*a*/x"
testRT "/*a*/null"
testRT "/*b*/false"
testRT "true/*c*/"
testRT "/*c*/true"
testRT "/*d*/0x1234fF"
testRT "/*e*/1.0e4"
testRT "/*x*/011"
testRT "/*f*/\"hello\\nworld\""
testRT "/*g*/'hello\\nworld'"
testRT "/*h*/this"
testRT "/*i*//blah/"
testRT "//j\nthis_"
it "arrays" $ do
testRT "/*a*/[/*b*/]"
testRT "/*a*/[/*b*/,/*c*/]"
testRT "/*a*/[/*b*/,/*c*/,/*d*/]"
testRT "/*a*/[/*b/*,/*c*/,/*d*/x/*e*/]"
testRT "/*a*/[/*b*/,/*c*/,/*d*/x/*e*/]"
testRT "/*a*/[/*b*/,/*c*/x/*d*/,/*e*/,/*f*/x/*g*/]"
testRT "/*a*/[/*b*/x/*c*/]"
testRT "/*a*/[/*b*/x/*c*/,/*d*/]"
it "object literals" $ do
testRT "/*a*/{/*b*/}"
testRT "/*a*/{/*b*/x/*c*/:/*d*/1/*e*/}"
testRT "/*a*/{/*b*/x/*c*/}"
testRT "/*a*/{/*b*/of/*c*/}"
testRT "x=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/y/*g*/:/*h*/2/*i*/}"
testRT "x=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/y/*g*/:/*h*/2/*i*/,/*j*/z/*k*/:/*l*/3/*m*/}"
testRT "a=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/}"
testRT "/*a*/{/*b*/[/*c*/x/*d*/+/*e*/y/*f*/]/*g*/:/*h*/1/*i*/}"
testRT "/*a*/{/*b*/a/*c*/(/*d*/x/*e*/,/*f*/y/*g*/)/*h*/{/*i*/}/*j*/}"
testRT "/*a*/{/*b*/[/*c*/x/*d*/+/*e*/y/*f*/]/*g*/(/*h*/)/*i*/{/*j*/}/*k*/}"
testRT "/*a*/{/*b*/*/*c*/a/*d*/(/*e*/x/*f*/,/*g*/y/*h*/)/*i*/{/*j*/}/*k*/}"
it "miscellaneous" $ do
testRT "/*a*/(/*b*/56/*c*/)"
testRT "/*a*/true/*b*/?/*c*/1/*d*/:/*e*/2"
testRT "/*a*/x/*b*/||/*c*/y"
testRT "/*a*/x/*b*/&&/*c*/y"
testRT "/*a*/x/*b*/|/*c*/y"
testRT "/*a*/x/*b*/^/*c*/y"
testRT "/*a*/x/*b*/&/*c*/y"
testRT "/*a*/x/*b*/==/*c*/y"
testRT "/*a*/x/*b*/!=/*c*/y"
testRT "/*a*/x/*b*/===/*c*/y"
testRT "/*a*/x/*b*/!==/*c*/y"
testRT "/*a*/x/*b*/</*c*/y"
testRT "/*a*/x/*b*/>/*c*/y"
testRT "/*a*/x/*b*/<=/*c*/y"
testRT "/*a*/x/*b*/>=/*c*/y"
testRT "/*a*/x /*b*/instanceof /*c*/y"
testRT "/*a*/x/*b*/=/*c*/{/*d*/get/*e*/ foo/*f*/(/*g*/)/*h*/ {/*i*/return/*j*/ 1/*k*/}/*l*/,/*m*/set/*n*/ foo/*o*/(/*p*/a/*q*/) /*r*/{/*s*/x/*t*/=/*u*/a/*v*/}/*w*/}"
testRT "x = { set foo(/*a*/[/*b*/a/*c*/,/*d*/b/*e*/]/*f*/=/*g*/y/*h*/) {} }"
testRT "... /*a*/ x"
testRT "a => {}"
testRT "(a) => { a + 2 }"
testRT "(a, b) => {}"
testRT "(a, b) => a + b"
testRT "() => { 42 }"
testRT "(...a) => a"
testRT "(a=1, b=2) => a + b"
testRT "([a, b]) => a + b"
testRT "({a, b}) => a + b"
testRT "function (...a) {}"
testRT "function (a=1, b=2) {}"
testRT "function ([a, ...b]) {}"
testRT "function ({a, b: c}) {}"
testRT "/*a*/function/*b*/*/*c*/f/*d*/(/*e*/)/*f*/{/*g*/yield/*h*/a/*i*/}/*j*/"
testRT "function*(a, b) { yield a ; yield b ; }"
testRT "/*a*/`<${/*b*/x/*c*/}>`/*d*/"
testRT "`\\${}`"
testRT "`\n\n`"
testRT "{}+``"
-- ^ https://github.com/erikd/language-javascript/issues/104
it "statement" $ do
testRT "if (1) {}"
testRT "if (1) {} else {}"
testRT "if (1) x=1; else {}"
testRT "do {x=1} while (true);"
testRT "do x=x+1;while(x<4);"
testRT "while(true);"
testRT "for(;;);"
testRT "for(x=1;x<10;x++);"
testRT "for(var x;;);"
testRT "for(var x=1;;);"
testRT "for(var x;y;z){}"
testRT "for(x in 5){}"
testRT "for(var x in 5){}"
testRT "for(let x;y;z){}"
testRT "for(let x in 5){}"
testRT "for(let x of 5){}"
testRT "for(const x;y;z){}"
testRT "for(const x in 5){}"
testRT "for(const x of 5){}"
testRT "for(x of 5){}"
testRT "for(var x of 5){}"
testRT "var x=1;"
testRT "const x=1,y=2;"
testRT "continue;"
testRT "continue x;"
testRT "break;"
testRT "break x;"
testRT "return;"
testRT "return x;"
testRT "with (x) {};"
testRT "abc:x=1"
testRT "switch (x) {}"
testRT "switch (x) {case 1:break;}"
testRT "switch (x) {case 0:\ncase 1:break;}"
testRT "switch (x) {default:break;}"
testRT "switch (x) {default:\ncase 1:break;}"
testRT "var x=1;let y=2;"
testRT "var [x, y]=z;"
testRT "let {x: [y]}=z;"
testRT "let yield=1"
it "module" $ do
testRTModule "import def from 'mod'"
testRTModule "import def from \"mod\";"
testRTModule "import * as foo from \"mod\" ; "
testRTModule "import def, * as foo from \"mod\" ; "
testRTModule "import { baz, bar as foo } from \"mod\" ; "
testRTModule "import def, { baz, bar as foo } from \"mod\" ; "
testRTModule "export {};"
testRTModule " export {} ; "
testRTModule "export { a , b , c };"
testRTModule "export { a, X as B, c }"
testRTModule "export {} from \"mod\";"
testRTModule "export const a = 1 ; "
testRTModule "export function f () { } ; "
testRTModule "export function * f () { } ; "
testRTModule "export class Foo\nextends Bar\n{ get a () { return 1 ; } static b ( x,y ) {} ; } ; "
testRT :: String -> Expectation
testRT = testRTWith readJs
testRTModule :: String -> Expectation
testRTModule = testRTWith readJsModule
testRTWith :: (String -> AST.JSAST) -> String -> Expectation
testRTWith f str = renderToString (f str) `shouldBe` str