packages feed

language-javascript 0.6.0.0 → 0.6.0.1

raw patch · 3 files changed

+350/−1 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

+ Tests/Minify.hs view
@@ -0,0 +1,250 @@+module Tests.Minify+    ( testMinifyExpr+    , testMinifyStmt+    , testMinifyProg+    ) where++import Control.Monad (forM_)+import Test.Hspec++import Language.JavaScript.Parser+import Language.JavaScript.Parser.Grammar5+import Language.JavaScript.Parser.Parser+import Language.JavaScript.Process.Minify+++testMinifyExpr :: Spec+testMinifyExpr = describe "Minify expressions:" $ do+    it "terminals" $ do+        minifyExpr " identifier " `shouldBe` "identifier"+        minifyExpr " 1 " `shouldBe` "1"+        minifyExpr " this " `shouldBe` "this"+        minifyExpr " 0x12ab " `shouldBe` "0x12ab"+        minifyExpr " 0567 " `shouldBe` "0567"+        minifyExpr " 'helo' " `shouldBe` "'helo'"+        minifyExpr " \"good bye\" " `shouldBe` "\"good bye\""+        minifyExpr " /\\n/g " `shouldBe` "/\\n/g"++    it "array literals" $ do+        minifyExpr " [ ] " `shouldBe` "[]"+        minifyExpr " [ , ] " `shouldBe` "[,]"+        minifyExpr " [ , , ] " `shouldBe` "[,,]"+        minifyExpr " [ x ] " `shouldBe` "[x]"+        minifyExpr " [ x , y ] " `shouldBe` "[x,y]"++    it "object literals" $ do+        minifyExpr " { } " `shouldBe` "{}"+        minifyExpr " { a : 1 } " `shouldBe` "{a:1}"+        minifyExpr " { b : 2 , } " `shouldBe` "{b:2}"+        minifyExpr " { c : 3 , d : 4 , } " `shouldBe` "{c:3,d:4}"+        minifyExpr " { 'str' : true , 42 : false , } " `shouldBe` "{'str':true,42:false}"++    it "parentheses" $ do+        minifyExpr " ( 'hello' ) " `shouldBe` "('hello')"+        minifyExpr " ( 12 ) " `shouldBe` "(12)"+        minifyExpr " ( 1 + 2 ) " `shouldBe` "(1+2)"++    it "unary" $ do+        minifyExpr " a -- " `shouldBe` "a--"+        minifyExpr " delete b " `shouldBe` "delete b"+        minifyExpr " c ++ " `shouldBe` "c++"+        minifyExpr " - d " `shouldBe` "-d"+        minifyExpr " ! e " `shouldBe` "!e"+        minifyExpr " + f " `shouldBe` "+f"+        minifyExpr " ~ g " `shouldBe` "~g"+        minifyExpr " typeof h " `shouldBe` "typeof h"+        minifyExpr " void i " `shouldBe` "void i"++    it "binary" $ do+        minifyExpr " a && z " `shouldBe` "a&&z"+        minifyExpr " b & z " `shouldBe` "b&z"+        minifyExpr " c | z " `shouldBe` "c|z"+        minifyExpr " d ^ z " `shouldBe` "d^z"+        minifyExpr " e / z " `shouldBe` "e/z"+        minifyExpr " f == z " `shouldBe` "f==z"+        minifyExpr " g >= z " `shouldBe` "g>=z"+        minifyExpr " h > z " `shouldBe` "h>z"+        minifyExpr " i in z " `shouldBe` "i in z"+        minifyExpr " j instanceof z " `shouldBe` "j instanceof z"+        minifyExpr " k <= z " `shouldBe` "k<=z"+        minifyExpr " l << z " `shouldBe` "l<<z"+        minifyExpr " m < z " `shouldBe`  "m<z"+        minifyExpr " n - z " `shouldBe`  "n-z"+        minifyExpr " o % z " `shouldBe`  "o%z"+        minifyExpr " p != z " `shouldBe`  "p!=z"+        minifyExpr " q || z " `shouldBe`  "q||z"+        minifyExpr " r + z " `shouldBe`  "r+z"+        minifyExpr " s >> z " `shouldBe`  "s>>z"+        minifyExpr " t === z " `shouldBe`  "t===z"+        minifyExpr " u !== z " `shouldBe`  "u!==z"+        minifyExpr " v * z " `shouldBe`  "v*z"+        minifyExpr " w >>> z " `shouldBe`  "w>>>z"++    it "ternary" $ do+        minifyExpr "  true ? 1 : 2 " `shouldBe` "true?1:2"+        minifyExpr "  x ? y + 1 : j - 1 " `shouldBe` "x?y+1:j-1"++    it "member access" $ do+        minifyExpr " a . b " `shouldBe` "a.b"+        minifyExpr " c . d . e " `shouldBe` "c.d.e"++    it "new" $ do+        minifyExpr " new f ( ) " `shouldBe` "new f()"+        minifyExpr " new g ( 1 ) " `shouldBe` "new g(1)"+        minifyExpr " new h ( 1 , 2 ) " `shouldBe` "new h(1,2)"+        minifyExpr " new k . x " `shouldBe` "new k.x"++    it "array access" $ do+        minifyExpr " i [ a ] " `shouldBe` "i[a]"+        minifyExpr " j [ a ] [ b ]" `shouldBe` "j[a][b]"++    it "function" $ do+        minifyExpr " function ( ) { } " `shouldBe` "function(){}"+        minifyExpr " function ( a ) { } " `shouldBe` "function(a){}"+        minifyExpr " function ( a , b ) { return a + b ; } " `shouldBe` "function(a,b){return a+b}"++    it "calls" $ do+        minifyExpr " a ( ) " `shouldBe` "a()"+        minifyExpr " b ( ) ( ) " `shouldBe` "b()()"+        minifyExpr " c ( ) [ x ] "  `shouldBe` "c()[x]"+        minifyExpr " d ( ) . y " `shouldBe` "d().y"++    it "property accessor" $ do+        minifyExpr " { get foo ( ) { return x } } " `shouldBe` "{get foo(){return x}}"+        minifyExpr " { set foo ( a ) { x = a } } " `shouldBe` "{set foo(a){x=a}}"++    it "string concatenation" $ do+        minifyExpr " 'ab' + \"cd\" " `shouldBe` "'abcd'"+        minifyExpr " \"bc\" + 'de' " `shouldBe` "\"bcde\""+        minifyExpr " \"cd\" + 'ef' + 'gh' " `shouldBe` "\"cdefgh\""+        -- TODO: Correct, but can we do better?+        minifyExpr " 'de' + \"'fg'\" + 'hi' " `shouldBe` "'de'+\"'fg'\"+'hi'"+++testMinifyStmt :: Spec+testMinifyStmt = describe "Minify statements:" $ do+    forM_ [ "break", "continue", "return" ] $ \kw ->+        it kw $ do+            minifyStmt (" " ++ kw ++ " ; ") `shouldBe` kw+            minifyStmt (" {" ++ kw ++ " ;} ") `shouldBe` kw+            minifyStmt (" " ++ kw ++ " x ; ") `shouldBe` (kw ++ " x")+            minifyStmt ("\n\n" ++ kw ++ " x ;\n") `shouldBe` (kw ++ " x")++    it "block" $ do+        minifyStmt "\n{ a = 1\nb = 2\n } " `shouldBe` "{a=1;b=2}"+        minifyStmt " { c = 3 ; d = 4 ; } " `shouldBe` "{c=3;d=4}"+        minifyStmt " { ; e = 1 } " `shouldBe` "e=1"+        minifyStmt " { { } ; f = 1 ; { } ; } ; " `shouldBe` "f=1"++    it "if" $ do+        minifyStmt " if ( 1 ) return ; " `shouldBe` "if(1)return"+        minifyStmt " if ( 1 ) ; " `shouldBe` "if(1);"++    it "if/else" $ do+        minifyStmt " if ( a ) ; else break ; " `shouldBe` "if(a);else break"+        minifyStmt " if ( b ) break ; else break ; " `shouldBe` "if(b){break}else break"+        minifyStmt " if ( c ) continue ; else continue ; " `shouldBe` "if(c){continue}else continue"+        minifyStmt " if ( d ) return ; else return ; " `shouldBe` "if(d){return}else return"+        minifyStmt " if ( e ) { b = 1 } else c = 2 ;" `shouldBe` "if(e){b=1}else c=2"+        minifyStmt " if ( f ) { b = 1 } else { c = 2 ; d = 4 ; } ;" `shouldBe` "if(f){b=1}else{c=2;d=4}"+        minifyStmt " if ( g ) { ex ; } else { ex ; } ; " `shouldBe` "if(g){ex}else ex"+        minifyStmt " if ( h ) ; else if ( 2 ){ 3 ; } " `shouldBe` "if(h);else if(2)3"++    it "while" $ do+        minifyStmt " while ( x < 2 ) x ++ ; " `shouldBe` "while(x<2)x++"+        minifyStmt " while ( x < 0x12 && y > 1 ) { x *= 3 ; y += 1 ; } ; " `shouldBe` "while(x<0x12&&y>1){x*=3;y+=1}"++    it "do/while" $ do+        minifyStmt " do x = foo (y) ; while ( x < y ) ; " `shouldBe` "do{x=foo(y)}while(x<y)"+        minifyStmt " do { x = foo (x, y) ; y -- ; } while ( x > y ) ; " `shouldBe` "do{x=foo(x,y);y--}while(x>y)"++    it "for" $ do+        minifyStmt " for ( ; ; ) ; " `shouldBe` "for(;;);"+        minifyStmt " for ( k = 0 ; k <= 10 ; k ++ ) ; " `shouldBe` "for(k=0;k<=10;k++);"+        minifyStmt " for ( k = 0, j = 1 ; k <= 10 && j < 10 ; k ++ , j -- ) ; " `shouldBe` "for(k=0,j=1;k<=10&&j<10;k++,j--);"+        minifyStmt " for (var x ; y ; z) { } " `shouldBe` "for(var x;y;z){}"+        minifyStmt " for ( x in 5 ) foo (x) ;" `shouldBe` "for(x in 5)foo(x)"+        minifyStmt " for ( var x in 5 ) { foo ( x++ ); y ++ ; } ;" `shouldBe` "for(var x in 5){foo(x++);y++}"++    it "labelled" $ do+        minifyStmt " start : while ( true ) { if ( i ++ < 3 ) continue start ; break ; } ; " `shouldBe` "start:while(true){if(i++<3)continue start;break}"+        minifyStmt " { k ++ ; start : while ( true ) { if ( i ++ < 3 ) continue start ; break ; } ; } ; " `shouldBe` "{k++;start:while(true){if(i++<3)continue start;break}}"++    it "function" $ do+        minifyStmt " function f ( ) { } ; " `shouldBe` "function f(){}"+        minifyStmt " function f ( a ) { } ; " `shouldBe` "function f(a){}"+        minifyStmt " function f ( a , b ) { return a + b ; } ; " `shouldBe` "function f(a,b){return a+b}"++    it "with" $ do+        minifyStmt " with ( x ) { } ; " `shouldBe` "with(x){}"+        minifyStmt " with ({ first: 'John' }) { foo ('Hello '+first); }" `shouldBe` "with({first:'John'})foo('Hello '+first)"++    it "throw" $ do+        minifyStmt " throw a " `shouldBe` "throw a"+        minifyStmt " throw b ; " `shouldBe` "throw b"+        minifyStmt " { throw c ; } ;" `shouldBe` "throw c"++    it "switch" $ do+        minifyStmt " switch ( a ) { } ; " `shouldBe` "switch(a){}"+        minifyStmt " switch ( b ) { case 1 : 1 ; case 2 : 2 ; } ;" `shouldBe` "switch(b){case 1:1;case 2:2}"+        minifyStmt " switch ( c ) { case 1 : case 'a': case \"b\" : break ; default : break ; } ; " `shouldBe` "switch(c){case 1:case'a':case\"b\":break;default:break}"+        minifyStmt " switch ( d ) { default : if (a) {x} else y ; if (b) { x } else y ; }" `shouldBe` "switch(d){default:if(a){x}else y;if(b){x}else y}"++    it "try/catch/finally" $ do+        minifyStmt " try { } catch ( a ) { } " `shouldBe` "try{}catch(a){}"+        minifyStmt " try { b } finally { } " `shouldBe` "try{b}finally{}"+        minifyStmt " try { } catch ( c ) { } finally { } " `shouldBe` "try{}catch(c){}finally{}"+        minifyStmt " try { } catch ( d ) { } catch ( x ){ } finally { } " `shouldBe` "try{}catch(d){}catch(x){}finally{}"+        minifyStmt " try { } catch ( e ) { } catch ( y ) { } " `shouldBe` "try{}catch(e){}catch(y){}"+        minifyStmt " try { } catch ( f  if f == x ) { } catch ( z ) { } " `shouldBe` "try{}catch(f if f==x){}catch(z){}"++    it "variable declaration" $ do+        minifyStmt " var a  " `shouldBe` "var a"+        minifyStmt " var b ; " `shouldBe` "var b"+        minifyStmt " var c = 1 ; " `shouldBe` "var c=1"+        minifyStmt " var d = 1, x = 2 ; " `shouldBe` "var d=1,x=2"++    it "string concatenation" $+        minifyStmt " f (\"ab\"+\"cd\") " `shouldBe` "f(\"abcd\")"+++testMinifyProg :: Spec+testMinifyProg = describe "Minify programs:" $ do+    it "simple" $ do+        minifyProg " a = f ? e : g ; " `shouldBe` "a=f?e:g"+        minifyProg " for ( i = 0 ; ; ) { ; var t = 1 ; } " `shouldBe` "for(i=0;;)var t=1"+    it "if" $+        minifyProg " if ( x ) { } ; t ; " `shouldBe` "if(x);t"+    it "if/else" $ do+        minifyProg " if ( a ) { } else { } ; break ; " `shouldBe` "if(a){}else;break"+        minifyProg " if ( b ) {x = 1} else {x = 2} f () ; " `shouldBe` "if(b){x=1}else x=2;f()"+    it "empty block" $ do+        minifyProg " a = 1 ; { } ; " `shouldBe`  "a=1"+        minifyProg " { } ; b = 1 ; " `shouldBe`  "b=1"+    it "empty statement" $ do+        minifyProg " a = 1 + b ; c ; ; { d ; } ; " `shouldBe` "a=1+b;c;d"+        minifyProg " b = a + 2 ; c ; { d ; } ; ; " `shouldBe` "b=a+2;c;d"+    it "nested block" $ do+        minifyProg "{a;;x;};y;z;;" `shouldBe` "a;x;y;z"+        minifyProg "{b;;{x;y;};};z;;" `shouldBe` "b;x;y;z"+    it "functions" $+        minifyProg " function f() {} ; function g() {} ;" `shouldBe` "function f(){}\nfunction g(){}"+    it "variable declaration" $ do+        minifyProg " var a = 1 ; var b = 2 ;" `shouldBe` "var a=1,b=2"+        minifyProg " var c=1;var d=2;var e=3;" `shouldBe` "var c=1,d=2,e=3"+        minifyProg " const f = 1 ; const g = 2 ;" `shouldBe` "const f=1,g=2"+        minifyProg " var h = 1 ; const i = 2 ;" `shouldBe` "var h=1;const i=2"+    it "try/catch/finally" $+        minifyProg " try { } catch (a) {} finally {} ; try { } catch ( b ) { } ; " `shouldBe` "try{}catch(a){}finally{}try{}catch(b){}"++-- -----------------------------------------------------------------------------+-- Minify test helpers.++minifyExpr :: String -> String+minifyExpr str = either id (renderToString . minifyJS) (parseUsing parseExpression str "src")++minifyStmt :: String -> String+minifyStmt str = either id (renderToString . minifyJS) (parseUsing parseStatement str "src")++minifyProg :: String -> String+minifyProg str = either id (renderToString . minifyJS) (parseUsing parseProgram str "src")
+ Tests/RoundTrip.hs view
@@ -0,0 +1,97 @@+module Tests.RoundTrip+    ( testRoundTrip+    ) where++import Test.Hspec++import Language.JavaScript.Parser+++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 "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*/}"++    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*/instance of /*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*/}"++    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 "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 :: String -> Expectation+testRT str = str `shouldBe` renderToString (readJs str)+
language-javascript.cabal view
@@ -1,5 +1,5 @@ Name:                language-javascript-Version:             0.6.0.0+Version:             0.6.0.1 Synopsis:            Parser for JavaScript Description:         Parses Javascript into an Abstract Syntax Tree (AST).  Initially intended as frontend to hjsmin.                      .@@ -77,7 +77,9 @@   Other-modules:    Tests.ExpressionParser                     Tests.Lexer                     Tests.LiteralParser+                    Tests.Minify                     Tests.ProgramParser+                    Tests.RoundTrip                     Tests.StatementParser   ghc-options:   -Wall -fwarn-tabs