import Data.Char import Language.JavaScript.Parser import Test.Framework (defaultMain, testGroup, Test) import Test.Framework.Providers.HUnit import Test.HUnit hiding (Test) import qualified Data.ByteString.Lazy as LB import qualified Data.Text as T import qualified Data.Text.Encoding as E import Text.Jasmine import Text.Jasmine.Pretty main :: IO () main = defaultMain [ testSuite , testSuiteMin , testSuiteFiles , testSuiteFilesUnminified ] testSuite :: Test testSuite = testGroup "Text.Jasmine.Parse" [ testCase "helloWorld" caseHelloWorld , testCase "helloWorld2" caseHelloWorld2 , testCase "simpleAssignment" caseSimpleAssignment , testCase "emptyFor" caseEmptyFor , testCase "fullFor" caseFullFor , testCase "forVarFull" caseForVarFull , testCase "ifelse1" caseIfElse1 , testCase "ifelse2" caseIfElse2 , testCase "0_f.js" case0_f , testCase "01_semi1.js" case01_semi1 , testCase "min_100_animals" case_min_100_animals , testCase "mergeStrings" caseMergeStrings , testCase "TrailingCommas" caseTrailingCommas , testCase "GetSet" caseGetSet , testCase "Unicode" caseUnicode , testCase "Issue3" caseIssue3 , testCase "Issue4" caseIssue4 , testCase "Switch1" caseSwitch1 , testCase "If1" caseIf1 , testCase "If2" caseIf2 , testCase "If3" caseIf3 , testCase "BootstrapDropdown" caseBootstrapDropdown , testCase "Issue8" caseIssue8 , testCase "Issue9" caseIssue9 , testCase "Issue14" caseIssue14 ] testSuiteMin :: Test testSuiteMin = testGroup "Text.Jasmine.Pretty Min" [ testCase "helloWorld" caseMinHelloWorld , testCase "helloWorld2" caseMinHelloWorld2 , testCase "simpleAssignment" caseMinSimpleAssignment , testCase "ifelse1" caseMinIfElse1 , testCase "ifelse2" caseMinIfElse2 , testCase "ifelse3" caseMinIfElse3 , testCase "0_f.js" caseMin0_f , testCase "01_semi1.js" caseMin01_semi1 , testCase "min_100_animals" caseMin_min_100_animals , testCase "minNestedSquare" caseMinNestedSquare , testCase "minMergeStrings" caseMinMergeStrings , testCase "EitherLeft" caseEitherLeft , testCase "EitherRight" caseEitherRight , testCase "TrailingCommas" caseMinTrailingCommas , testCase "GetSet" caseMinGetSet , testCase "Unicode" caseMinUnicode , testCase "MinIssue3" caseMinIssue3 , testCase "MinIssue4" caseMinIssue4 , testCase "MinSwitch1" caseMinSwitch1 , testCase "MinIf1" caseMinIf1 , testCase "MinIf2" caseMinIf2 , testCase "MinIf3" caseMinIf3 , testCase "MinBootstrapDropdown" caseMinBootstrapDropdown , testCase "MinIssue8" caseMinIssue8 , testCase "MinIssue9" caseMinIssue9 , testCase "MinIssue14" caseMinIssue14 ] testSuiteFiles :: Test testSuiteFiles = testGroup "Text.Jasmine.Pretty files" [ testCase "00_f.js" (testFile "./test/pminified/00_f.js") , testCase "01_semi1.js" (testFile "./test/pminified/01_semi1.js") , testCase "02_sm.js" (testFile "./test/pminified/02_sm.js") , testCase "03_sm.js" (testFile "./test/pminified/03_sm.js") , testCase "04_if.js" (testFile "./test/pminified/04_if.js") , testCase "05_comments_simple.js" (testFile "./test/pminified/05_comments_simple.js") , testCase "05_regex.js" (testFile "./test/pminified/05_regex.js") , testCase "06_callexpr.js" (testFile "./test/pminified/06_callexpr.js") , testCase "06_newexpr.js" (testFile "./test/pminified/06_newexpr.js") , testCase "06_var.js" (testFile "./test/pminified/06_var.js") , testCase "07_expr.js" (testFile "./test/pminified/07_expr.js") , testCase "10_switch.js" (testFile "./test/pminified/10_switch.js") , testCase "14_labelled_stmts.js" (testFile "./test/pminified/14_labelled_stmts.js") , testCase "15_literals.js" (testFile "./test/pminified/15_literals.js") , testCase "16_literals.js" (testFile "./test/pminified/16_literals.js") , testCase "20_statements.js" (testFile "./test/pminified/20_statements.js") , testCase "20_continue_loop.js" (testFile "./test/pminified/20_continue_loop.js") , testCase "25_trycatch.js" (testFile "./test/pminified/25_trycatch.js") , testCase "40_functions.js" (testFile "./test/pminified/40_functions.js") , testCase "67_bob.js" (testFile "./test/pminified/67_bob.js") , testCase "110_perfect.js" (testFile "./test/pminified/110_perfect.js") , testCase "120_js.js" (testFile "./test/pminified/120_js.js") , testCase "121_jsdefs.js" (testFile "./test/pminified/121_jsdefs.js") , testCase "122_jsexec.js" (testFile "./test/pminified/122_jsexec.js") , testCase "122_jsexec2.js" (testFile "./test/pminified/122_jsexec2.js") , testCase "122_jsexec3.js" (testFile "./test/pminified/122_jsexec3.js") -- , testCase "123_jsparse.js" (testFile "./test/pminified/123_jsparse.js") -- TODO: something strange here, assigning code block to variable? -- See http://msdn.microsoft.com/en-us/library/77kz8hy0.aspx, get/set keywords for object accessors --, testCase "130_htojs2.js" (testFile "./test/parsingonly/130_htojs2.js") --, testCase "" (testFile "./test/pminified/") ] testSuiteFilesUnminified :: Test testSuiteFilesUnminified = testGroup "Text.Jasmine.Pretty filesUnminified" [ testCase "00_f.js" (testFileUnminified "00_f.js") , testCase "01_semi1.js" (testFileUnminified "01_semi1.js") , testCase "02_sm.js" (testFileUnminified "02_sm.js") , testCase "03_sm.js" (testFileUnminified "03_sm.js") , testCase "04_if.js" (testFileUnminified "04_if.js") , testCase "05_comments_simple.js" (testFileUnminified "05_comments_simple.js") , testCase "05_regex.js" (testFileUnminified "05_regex.js") , testCase "06_callexpr.js" (testFileUnminified "06_callexpr.js") , testCase "06_newexpr.js" (testFileUnminified "06_newexpr.js") , testCase "06_var.js" (testFileUnminified "06_var.js") , testCase "07_expr.js" (testFileUnminified "07_expr.js") , testCase "10_switch.js" (testFileUnminified "10_switch.js") , testCase "14_labelled_stmts.js" (testFileUnminified "14_labelled_stmts.js") , testCase "15_literals.js" (testFileUnminified "15_literals.js") , testCase "16_literals.js" (testFileUnminified "16_literals.js") , testCase "20_statements.js" (testFileUnminified "20_statements.js") , testCase "25_trycatch.js" (testFileUnminified "25_trycatch.js") , testCase "40_functions.js" (testFileUnminified "40_functions.js") , testCase "67_bob.js" (testFileUnminified "67_bob.js") , testCase "110_perfect.js" (testFileUnminified "110_perfect.js") , testCase "120_js.js" (testFileUnminified "120_js.js") , testCase "121_jsdefs.js" (testFileUnminified "121_jsdefs.js") , testCase "122_jsexec.js" (testFileUnminified "122_jsexec.js") --, testCase "122_jsexec2.js" (testFileUnminified "122_jsexec2.js") ] srcHelloWorld = "function Hello(a) {}" caseHelloWorld = "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSBlock ([])),JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcHelloWorld) caseMinHelloWorld = -- "function Hello(a){}" @=? (minify (U.fromString srcHelloWorld)) testMinify "function Hello(a){}" srcHelloWorld srcHelloWorld2 = "function Hello(a) {b=1}" caseHelloWorld2 = "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSBlock ([JSExpression [JSIdentifier \"b\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]])),JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcHelloWorld2) caseMinHelloWorld2 = -- "function Hello(a){b=1}" @=? (minify (U.fromString srcHelloWorld2)) testMinify "function Hello(a){b=1}" srcHelloWorld2 srcSimpleAssignment = "a=1;" caseSimpleAssignment = "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcSimpleAssignment) caseMinSimpleAssignment = testMinify "a=1" srcSimpleAssignment srcEmptyFor = "for (i = 0;;){}" caseEmptyFor = "Right (JSSourceElementsTop [JSFor [JSExpression [JSIdentifier \"i\",JSOperator JSLiteral \"=\",JSDecimal \"0\"]] [] [] (JSBlock ([])),JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcEmptyFor) srcFullFor = "for (i = 0;i<10;i++){}" caseFullFor = "Right (JSSourceElementsTop [JSFor [JSExpression [JSIdentifier \"i\",JSOperator JSLiteral \"=\",JSDecimal \"0\"]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"i\"] [JSDecimal \"10\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"i\"]]] (JSBlock ([])),JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcFullFor) srcForVarFull = "for(var i=0,j=tokens.length;i\" [JSIdentifier \"i\"] [JSDecimal \"0\"]]) ([JSExpression [JSIdentifier \"consts\",JSOperator JSLiteral \"+=\",JSStringLiteral '\"' \", \"],JSLiteral \";\"]) ([]),JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"t\") [JSLiteral \"=\",JSMemberSquare [JSIdentifier \"tokens\"] (JSExpression [JSIdentifier \"i\"])]],JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcIf1) caseMinIf1 = testMinify "if(i>0)consts+=\", \";var t=tokens[i]" srcIf1 srcIf2 = "if (getValue)\n execute;\nelse {\n execute;\n}" caseIf2 = "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"getValue\"]) ([JSExpression [JSIdentifier \"execute\"],JSLiteral \";\"]) ([JSLiteral \"else\",JSBlock ([JSExpression [JSIdentifier \"execute\"],JSLiteral \";\"])]),JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcIf2) caseMinIf2 = testMinify "if(getValue){execute}else execute" srcIf2 srcIf3 = "if(getValue){execute}else execute" caseIf3 = "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"getValue\"]) ([JSExpression [JSIdentifier \"execute\"],JSLiteral \";\"]) ([JSLiteral \"else\",JSBlock ([JSExpression [JSIdentifier \"execute\"],JSLiteral \";\"])]),JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcIf2) caseMinIf3 = testMinify "if(getValue){execute}else execute" srcIf3 srcBootstrapDropdown = "clearMenus()\n!isActive && $parent.toggleClass('open')" caseBootstrapDropdown = "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"clearMenus\",JSArguments []],JSExpression [JSExpressionBinary \"&&\" [JSUnary \"!\",JSIdentifier \"isActive\"] [JSMemberDot [JSIdentifier \"$parent\"] (JSIdentifier \"toggleClass\"),JSArguments [JSStringLiteral '\\'' \"open\"]]],JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcBootstrapDropdown) caseMinBootstrapDropdown = testMinify "clearMenus();!isActive&&$parent.toggleClass('open')" srcBootstrapDropdown srcIssue8 = "(function(){new nicEditor({fullPanel:true}).panelInstance('h4')})();" caseIssue8 = "Right (JSSourceElementsTop [JSExpression [JSExpressionParen (JSExpression [JSFunctionExpression [] [] (JSBlock ([JSExpression [JSMemberDot [JSLiteral \"new\",JSIdentifier \"nicEditor\",JSArguments [JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"fullPanel\") [JSLiteral \"true\"]]]] (JSIdentifier \"panelInstance\"),JSArguments [JSStringLiteral '\\'' \"h4\"]]]))]),JSArguments []],JSLiteral \";\",JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcIssue8) caseMinIssue8 = testMinify "(function(){new nicEditor({fullPanel:true}).panelInstance('h4')})()" srcIssue8 srcIssue9 = "var x = [new friend(5)];" caseIssue9 = "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"x\") [JSLiteral \"=\",JSArrayLiteral [JSLiteral \"new\",JSIdentifier \"friend\",JSArguments [JSDecimal \"5\"]]]],JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcIssue9) caseMinIssue9 = testMinify "var x=[new friend(5)]" srcIssue9 srcIssue14 = "var settings = {start : new Date(2012, 01, 27)};" caseIssue14 = "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"settings\") [JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"start\") [JSLiteral \"new\",JSIdentifier \"Date\",JSArguments [JSDecimal \"2012\",JSLiteral \",\",JSOctal \"01\",JSLiteral \",\",JSDecimal \"27\"]]]]],JSLiteral \"\"])" @=? showStrippedMaybe (parseProgram srcIssue14) caseMinIssue14 = testMinify "var settings={start:new Date(2012,01,27)}" srcIssue14 -- --------------------------------------------------------------------- -- utilities testMinify expected src = LB.fromChunks [E.encodeUtf8 (T.pack expected)] @=? minify (LB.fromChunks [E.encodeUtf8 (T.pack src)]) testFile :: FilePath -> IO () testFile filename = do x <- readFile filename let x' = trim x testMinify x' x' testFileUnminified :: FilePath -> IO () testFileUnminified filename = do x <- readFile ("./test/pminified/" ++ filename) y <- readFile ("./test/parsingonly/" ++ filename) let x' = trim x testMinify x' y trim :: String -> String trim = let f = reverse . dropWhile isSpace in f . f -- For language-javascript parseProgram src = parse src "src"