language-dart 0.1.0.0 → 0.2.0.0
raw patch · 7 files changed
+455/−437 lines, 7 filesdep +raw-strings-qqPVP ok
version bump matches the API change (PVP)
Dependencies added: raw-strings-qq
API changes (from Hackage documentation)
- Language.Dart.Syntax: SimpleFormalParameter :: (Maybe Comment) -> [Annotation] -> FinalVarOrType -> SimpleIdentifier -> NormalFormalParameter
+ Language.Dart.Syntax: SimpleFormalParameter :: (Maybe Comment) -> [Annotation] -> (Maybe FinalVarOrType) -> SimpleIdentifier -> NormalFormalParameter
Files
- CHANGELOG.md +4/−0
- language-dart.cabal +4/−1
- src/Language/Dart/Pretty.hs +1/−1
- src/Language/Dart/Syntax.hs +1/−1
- test/PrettySpec.hs +388/−0
- test/Spec.hs +1/−434
- test/TestHelper.hs +56/−0
CHANGELOG.md view
@@ -1,3 +1,7 @@+# 0.2.0.0++* Make the type field of SimpleFormalParameter optional+ # 0.1.0.0 * Initial release
language-dart.cabal view
@@ -1,5 +1,5 @@ name: language-dart-version: 0.1.0.0+version: 0.2.0.0 synopsis: Manipulating Dart source: abstract syntax and pretty-printer description: Please see README.md homepage: https://github.com/kseo/language-dart#readme@@ -27,9 +27,12 @@ type: exitcode-stdio-1.0 hs-source-dirs: test main-is: Spec.hs+ other-modules: PrettySpec+ TestHelper build-depends: base , hspec , language-dart+ , raw-strings-qq ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010
src/Language/Dart/Pretty.hs view
@@ -139,7 +139,7 @@ prettyPrec p (SimpleFormalParameter _ metadata kind identifier) = ppMetadata p metadata $$- hsep [ prettyPrec p kind+ hsep [ maybePP p kind , prettyPrec p identifier ]
src/Language/Dart/Syntax.hs view
@@ -720,7 +720,7 @@ -- ('final' [TypeName] | 'var' | [TypeName])? [SimpleIdentifier] | SimpleFormalParameter (Maybe Comment) -- comment [Annotation] -- metadata- FinalVarOrType+ (Maybe FinalVarOrType) SimpleIdentifier -- identifier deriving (Eq, Show, Typeable, Generic, Data)
+ test/PrettySpec.hs view
@@ -0,0 +1,388 @@+{-# LANGUAGE QuasiQuotes #-}++module PrettySpec where++import Test.Hspec++import Language.Dart.Pretty+import Language.Dart.Syntax+import Text.RawString.QQ++import TestHelper++spec :: Spec+spec =+ describe "prettyPrint" $ do+ it "preserves operator precedence" $ do+ let l = BinaryExpression (intExp 1) "+" (intExp 2)+ r = BinaryExpression (intExp 3) "-" (intExp 2)+ e = BinaryExpression l "*" r+ prettyPrint e `shouldBe` "(1 + 2) * (3 - 2)"++ it "prints an import directive" $ do+ let libraryUri = strLit "package:analyzer/src/dart/ast/ast.dart"+ as = SimpleIdentifier "a"+ imp = ImportDirective Nothing+ []+ libraryUri+ []+ False+ (Just as)+ [ ShowCombinator [SimpleIdentifier "TypeName"]+ , ShowCombinator [SimpleIdentifier "ArgumentList"]+ ]+ prettyPrint imp `shouldBe` [r|import "package:analyzer/src/dart/ast/ast.dart" as a show TypeName, show ArgumentList;|]++ it "prints a function declaration" $ do+ let formals = FormalParameterList [formal numType "aNumber"]+ arg = Literal' . StringLiteral' . SingleStringLiteral' $+ StringInterpolation [ InterpolationString "The number is "+ , InterpolationExpression (identExp "aNumber")+ , InterpolationString "."]+ body = BlockFunctionBody Sync+ (Block [ ExpressionStatement (+ InvocationExpression (+ MethodInvocation Nothing+ (SimpleIdentifier "print")+ Nothing+ (ArgumentList [arg])))])+ funExp = FunctionExpression Nothing formals body+ funDecl = FunctionDeclaration Nothing [] False Nothing Empty (SimpleIdentifier "printNumber") funExp+ prettyPrint funDecl `shouldBe` [r|printNumber(num aNumber)+{+ print("The number is ${aNumber}.");+}|]++ it "prints an optional position parameter" $ do+ let formals = FormalParameterList [formal strType "from", formal strType "msg", posFormal strType "device"]+ str1 = Literal' . StringLiteral' . SingleStringLiteral' $+ StringInterpolation [ InterpolationExpression (identExp "from")+ , InterpolationString " says "+ , InterpolationExpression (identExp "msg")+ ]+ str2 = Literal' . StringLiteral' . SingleStringLiteral' $+ StringInterpolation [ InterpolationExpression (identExp "result")+ , InterpolationString " with a "+ , InterpolationExpression (identExp "device")+ ]+ body = BlockFunctionBody Sync+ (Block [ VariableDeclarationStatement (+ VariableDeclarationList Nothing+ []+ FCVTVar+ [VariableDeclaration (SimpleIdentifier "result") (Just str1)])+ , IfStatement (BinaryExpression (identExp "device") "!=" nullExp)+ (Block' (Block [ ExpressionStatement (+ AssignmentExpression (identExp "result") "=" str2)]))+ Nothing+ , ReturnStatement (Just (identExp "result"))+ ])+ funExp = FunctionExpression Nothing formals body+ funDecl = FunctionDeclaration Nothing [] False (Just strType) Empty (SimpleIdentifier "say") funExp+ prettyPrint funDecl `shouldBe` [r|String say(String from, String msg, [String device])+{+ var result = "${from} says ${msg}";+ if (device != null)+ {+ result = "${result} with a ${device}";+ }+ return result;+}|]++ it "prints an expression function" $ do+ let body = ExpressionFunctionBody False (+ ConditionalExpression (BinaryExpression (identExp "msg") "==" nullExp)+ (InvocationExpression+ (MethodInvocation (Just SuperExpression)+ (SimpleIdentifier "toString")+ Nothing+ (ArgumentList [])))+ (identExp "msg"))++ funExp = FunctionExpression Nothing (FormalParameterList []) body+ funDecl = FunctionDeclaration Nothing [] False (Just strType) Empty (SimpleIdentifier "toString") funExp+ prettyPrint funDecl `shouldBe` "String toString() => msg == null ? super.toString() : msg;"++ it "prints an enum" $ do+ let enumConstDecls = [ EnumConstantDeclaration Nothing [] (SimpleIdentifier "red")+ , EnumConstantDeclaration Nothing [] (SimpleIdentifier "green")+ , EnumConstantDeclaration Nothing [] (SimpleIdentifier "blue")+ ]+ enumDecl = EnumDeclaration Nothing [] (SimpleIdentifier "Color") enumConstDecls+ prettyPrint enumDecl `shouldBe` [r|enum Color+{+ red,+ green,+ blue+}|]++ it "prints a for loop" $ do+ let variableList = VariableDeclarationList Nothing+ []+ FCVTVar+ [VariableDeclaration (SimpleIdentifier "i") (Just (intExp 0))]+ condition = BinaryExpression (identExp "i") "<" (intExp 5)+ updater = PostfixExpression (identExp "i") "++"+ body = (Block' (Block [ ExpressionStatement (+ InvocationExpression (+ MethodInvocation (Just (identExp "message"))+ (SimpleIdentifier "write")+ Nothing+ (ArgumentList [strLitExp "!"])))]))+ forLoop = ForStatement (Just variableList)+ Nothing+ (Just condition)+ [updater]+ body+ prettyPrint forLoop `shouldBe` [r|for (var i = 0; i < 5; i++)+{+ message.write("!");+}|]++ it "prints a list literal" $ do+ let litExp = Literal' . TypedLiteral $ ListLiteral False Nothing [intExp 0, intExp 1, intExp 2]+ prettyPrint litExp `shouldBe` "[0, 1, 2]"++ it "prints parameterized types" $ do+ let consName = ConstructorName (TypeName (SimpleIdentifier' (SimpleIdentifier "Map"))+ (Just (TypeArgumentList [tyName "int", tyName "View"])))+ Nothing+ let exp = InstanceCreationExpression NCNew consName (ArgumentList [])+ prettyPrint exp `shouldBe` "new Map<int, View>()"++ it "prints a switch statement" $ do+ let switchMembers = [ SwitchCase [] (strLitExp "CLOSED") [funStmt "executeClosed", (BreakStatement Nothing)]+ , SwitchCase [] (strLitExp "PENDING") [funStmt "executePending", (BreakStatement Nothing)]+ , SwitchCase [] (strLitExp "APPROVED") [funStmt "executeApproved", (BreakStatement Nothing)]+ , SwitchCase [] (strLitExp "DENIED") [funStmt "executeDenied", (BreakStatement Nothing)]+ , SwitchCase [] (strLitExp "OPEN") [funStmt "executeOpen", (BreakStatement Nothing)]+ , SwitchDefault [] [funStmt "executeUnknown"]+ ]+ switch = SwitchStatement (identExp "command") switchMembers+ prettyPrint switch `shouldBe` [r|switch (command)+{+ case "CLOSED":+ executeClosed();+ break;+ case "PENDING":+ executePending();+ break;+ case "APPROVED":+ executeApproved();+ break;+ case "DENIED":+ executeDenied();+ break;+ case "OPEN":+ executeOpen();+ break;+ default:+ executeUnknown();+}|]++ it "prints a try statement" $ do+ let arg = Literal' . StringLiteral' . SingleStringLiteral' $+ StringInterpolation [ InterpolationString "Error: "+ , InterpolationExpression (identExp "e")+ ]+ try = TryStatement (Block [funStmt "breedMoreLlamas"])+ [CatchClause Nothing (SimpleIdentifier "e") Nothing (Block [funStmt1 "print" arg])]+ (Just (Block [funStmt "cleanLlamaStalls"]))+ prettyPrint try `shouldBe` [r|try+{+ breedMoreLlamas();+}+catch (e)+{+ print("Error: ${e}");+}+finally+{+ cleanLlamaStalls();+}|]++ it "prints a constructor" $ do+ let varDeclList ty name = VariableDeclarationList Nothing+ []+ (FCVTType (tyName ty))+ [VariableDeclaration (SimpleIdentifier name) Nothing]++ returnType = SimpleIdentifier' (SimpleIdentifier "Point")+ consFormals1 = FormalParameterList [ NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "x"))+ , NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "y"))+ ]+ consFormals2 = FormalParameterList [ NormalFormalParameter' (+ FieldFormalParameter Nothing+ []+ (Just (FCVTType (tyName "Map")))+ False+ (SimpleIdentifier "json"))+ ]+ methodFormals = FormalParameterList [ NormalFormalParameter' (+ FieldFormalParameter Nothing+ []+ (Just (FCVTType (tyName "Point")))+ False+ (SimpleIdentifier "other"))+ ]+ consBody = BlockFunctionBody Sync+ (Block [ ExpressionStatement (+ AssignmentExpression (identExp "x")+ "="+ (IndexExpressionForTarget (identExp "json") (strLitExp "x")))+ , ExpressionStatement (+ AssignmentExpression (identExp "y")+ "="+ (IndexExpressionForTarget (identExp "json") (strLitExp "y")))+ ])+ exp1 = BinaryExpression (identExp "x") "-" (PropertyAccess (identExp "other") (SimpleIdentifier "x"))+ exp2 = BinaryExpression (identExp "y") "-" (PropertyAccess (identExp "other") (SimpleIdentifier "y"))+ methodBody = BlockFunctionBody Sync+ (Block [ VariableDeclarationStatement (+ VariableDeclarationList Nothing+ []+ FCVTVar+ [VariableDeclaration (SimpleIdentifier "dx") (Just exp1)])+ , VariableDeclarationStatement (+ VariableDeclarationList Nothing+ []+ FCVTVar+ [VariableDeclaration (SimpleIdentifier "dy") (Just exp2)])+ , ReturnStatement (Just (+ InvocationExpression (+ MethodInvocation Nothing+ (SimpleIdentifier "sqrt")+ Nothing+ (ArgumentList [BinaryExpression (BinaryExpression (identExp "dx") "*" (identExp "dx"))+ "+"+ (BinaryExpression (identExp "dy") "*" (identExp "dy"))]))))+ ])+ classMembers = [ FieldDeclaration Nothing [] False (varDeclList "num" "x")+ , FieldDeclaration Nothing [] False (varDeclList "num" "y")+ , ConstructorDeclaration Nothing [] False False False returnType Nothing consFormals1 [] Nothing Nothing+ , ConstructorDeclaration Nothing [] False False False returnType (Just (SimpleIdentifier "fromJson")) consFormals2 [] Nothing (Just consBody)+ , MethodDeclaration Nothing [] False Nothing (Just (tyName "num")) Empty False (SimpleIdentifier "distanceTo") Nothing (Just methodFormals) methodBody+ ]+ clazz = ClassDeclaration Nothing+ []+ False+ (SimpleIdentifier "Point")+ Nothing+ Nothing+ Nothing+ Nothing+ classMembers+ prettyPrint clazz `shouldBe` [r|class Point+{+ num x;+ num y;+ Point(this.x, this.y);+ Point.fromJson(Map json)+ {+ x = json["x"];+ y = json["y"];+ }+ num distanceTo(Point other)+ {+ var dx = x - other.x;+ var dy = y - other.y;+ return sqrt(dx * dx + dy * dy);+ }+}|]++ it "prints the initializer lists of a constructor" $ do+ let varDeclList ty name = VariableDeclarationList Nothing+ []+ (FCVTType (tyName ty))+ [VariableDeclaration (SimpleIdentifier name) Nothing]+ returnType = SimpleIdentifier' (SimpleIdentifier "Point")+ formals = FormalParameterList [ NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "x"))+ , NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "y"))+ ]+ exp = InvocationExpression (+ MethodInvocation Nothing+ (SimpleIdentifier "sqrt")+ Nothing+ (ArgumentList [BinaryExpression (BinaryExpression (identExp "x") "*" (identExp "x"))+ "+"+ (BinaryExpression (identExp "y") "*" (identExp "y"))]))+ classMembers = [ FieldDeclaration Nothing [] False (varDeclList "num" "x")+ , FieldDeclaration Nothing [] False (varDeclList "num" "y")+ , FieldDeclaration Nothing [] False (varDeclList "num" "distanceFromOrigin")+ , ConstructorDeclaration Nothing+ []+ False+ False+ False+ returnType+ Nothing+ formals+ [ ConstructorFieldInitializer False (SimpleIdentifier "x") (identExp "x")+ , ConstructorFieldInitializer False (SimpleIdentifier "y") (identExp "y")+ , ConstructorFieldInitializer False (SimpleIdentifier "distanceFromOrigin") exp+ ]+ Nothing+ Nothing+ ]+ clazz = ClassDeclaration Nothing+ []+ False+ (SimpleIdentifier "Point")+ Nothing+ Nothing+ Nothing+ Nothing+ classMembers++ prettyPrint clazz `shouldBe` [r|class Point+{+ num x;+ num y;+ num distanceFromOrigin;+ Point(this.x, this.y) : x = x,+ y = y,+ distanceFromOrigin = sqrt(x * x + y * y);+}|]++ it "prints the implement clause" $ do+ let implements = ImplementsClause [tyName "Comparable", tyName "Location"]+ clazz = ClassDeclaration Nothing+ []+ False+ (SimpleIdentifier "Point")+ Nothing+ Nothing+ Nothing+ (Just implements)+ []+ prettyPrint clazz `shouldBe` [r|class Point implements Comparable, Location+{+}|]++ it "prints the metadata" $ do+ let annotation = Annotation (SimpleIdentifier' (SimpleIdentifier "override")) Nothing Nothing+ methodFormals = FormalParameterList [ NormalFormalParameter' (+ FieldFormalParameter Nothing+ []+ (Just (FCVTType (tyName "Invocation")))+ False+ (SimpleIdentifier "mirror"))+ ]+ methodDecl = MethodDeclaration Nothing+ [annotation]+ False+ Nothing+ (Just (tyName "void"))+ Empty+ False+ (SimpleIdentifier "noSuchMethod")+ Nothing+ (Just methodFormals)+ (BlockFunctionBody Sync (Block []))+ prettyPrint methodDecl `shouldBe` [r|@override+void noSuchMethod(Invocation mirror)+{+}|]++main :: IO ()+main = hspec spec
test/Spec.hs view
@@ -1,434 +1,1 @@-import Test.Hspec--import Language.Dart.Pretty-import Language.Dart.Syntax--intExp :: Integer -> Expression-intExp = Literal' . IntegerLiteral--ident :: String -> Identifier-ident = SimpleIdentifier' . SimpleIdentifier--identExp :: String -> Expression-identExp = Identifier' . ident--tyName :: String -> TypeName-tyName name = TypeName (ident name) Nothing--strType = tyName "String"-numType = tyName "num"--formal :: TypeName -> String -> FormalParameter-formal ty p = NormalFormalParameter' $- SimpleFormalParameter Nothing [] (FVTType ty) (SimpleIdentifier p)--posFormal :: TypeName -> String -> FormalParameter-posFormal ty p = DefaultFormalParameter parameter Positional Nothing- where parameter = (SimpleFormalParameter Nothing [] (FVTType ty) (SimpleIdentifier p))--var :: String -> FormalParameter-var p = NormalFormalParameter' $- SimpleFormalParameter Nothing [] FVTVar (SimpleIdentifier p)--strLit :: String -> StringLiteral-strLit = SingleStringLiteral' . SimpleStringLiteral--strLitExp :: String -> Expression-strLitExp = Literal' . StringLiteral' . strLit--nullExp :: Expression-nullExp = Literal' NullLiteral--funStmt :: String -> Statement-funStmt name = ExpressionStatement (- InvocationExpression (- MethodInvocation Nothing- (SimpleIdentifier name)- Nothing- (ArgumentList [])))--funStmt1 :: String -> Expression -> Statement-funStmt1 name arg1 = ExpressionStatement (- InvocationExpression (- MethodInvocation Nothing- (SimpleIdentifier name)- Nothing- (ArgumentList [arg1])))--prettyPrintSpec :: Spec-prettyPrintSpec =- describe "prettyPrint" $ do- it "preserves operator precedence" $ do- let l = BinaryExpression (intExp 1) "+" (intExp 2)- r = BinaryExpression (intExp 3) "-" (intExp 2)- e = BinaryExpression l "*" r- prettyPrint e `shouldBe` "(1 + 2) * (3 - 2)"-- it "prints an import directive" $ do- let libraryUri = strLit "package:analyzer/src/dart/ast/ast.dart"- as = SimpleIdentifier "a"- imp = ImportDirective Nothing- []- libraryUri- []- False- (Just as)- [ ShowCombinator [SimpleIdentifier "TypeName"]- , ShowCombinator [SimpleIdentifier "ArgumentList"]- ]- prettyPrint imp `shouldBe` "import \"package:analyzer/src/dart/ast/ast.dart\" as a show TypeName, show ArgumentList;"-- it "prints a function declaration" $ do- let formals = FormalParameterList [formal numType "aNumber"]- arg = Literal' . StringLiteral' . SingleStringLiteral' $- StringInterpolation [ InterpolationString "The number is "- , InterpolationExpression (identExp "aNumber")- , InterpolationString "."]- body = BlockFunctionBody Sync- (Block [ ExpressionStatement (- InvocationExpression (- MethodInvocation Nothing- (SimpleIdentifier "print")- Nothing- (ArgumentList [arg])))])- funExp = FunctionExpression Nothing formals body- funDecl = FunctionDeclaration Nothing [] False Nothing Empty (SimpleIdentifier "printNumber") funExp- prettyPrint funDecl `shouldBe` "printNumber(num aNumber)\n\- \{\n\- \ print(\"The number is ${aNumber}.\");\n\- \}"-- it "prints an optional position parameter" $ do- let formals = FormalParameterList [formal strType "from", formal strType "msg", posFormal strType "device"]- str1 = Literal' . StringLiteral' . SingleStringLiteral' $- StringInterpolation [ InterpolationExpression (identExp "from")- , InterpolationString " says "- , InterpolationExpression (identExp "msg")- ]- str2 = Literal' . StringLiteral' . SingleStringLiteral' $- StringInterpolation [ InterpolationExpression (identExp "result")- , InterpolationString " with a "- , InterpolationExpression (identExp "device")- ]- body = BlockFunctionBody Sync- (Block [ VariableDeclarationStatement (- VariableDeclarationList Nothing- []- FCVTVar- [VariableDeclaration (SimpleIdentifier "result") (Just str1)])- , IfStatement (BinaryExpression (identExp "device") "!=" nullExp)- (Block' (Block [ ExpressionStatement (- AssignmentExpression (identExp "result") "=" str2)]))- Nothing- , ReturnStatement (Just (identExp "result"))- ])- funExp = FunctionExpression Nothing formals body- funDecl = FunctionDeclaration Nothing [] False (Just strType) Empty (SimpleIdentifier "say") funExp- prettyPrint funDecl `shouldBe` "String say(String from, String msg, [String device])\n\- \{\n\- \ var result = \"${from} says ${msg}\";\n\- \ if (device != null)\n\- \ {\n\- \ result = \"${result} with a ${device}\";\n\- \ }\n\- \ return result;\n\- \}"-- it "prints an expression function" $ do- let body = ExpressionFunctionBody False (- ConditionalExpression (BinaryExpression (identExp "msg") "==" nullExp)- (InvocationExpression- (MethodInvocation (Just SuperExpression)- (SimpleIdentifier "toString")- Nothing- (ArgumentList [])))- (identExp "msg"))-- funExp = FunctionExpression Nothing (FormalParameterList []) body- funDecl = FunctionDeclaration Nothing [] False (Just strType) Empty (SimpleIdentifier "toString") funExp- prettyPrint funDecl `shouldBe` "String toString() => msg == null ? super.toString() : msg;"-- it "prints an enum" $ do- let enumConstDecls = [ EnumConstantDeclaration Nothing [] (SimpleIdentifier "red")- , EnumConstantDeclaration Nothing [] (SimpleIdentifier "green")- , EnumConstantDeclaration Nothing [] (SimpleIdentifier "blue")- ]- enumDecl = EnumDeclaration Nothing [] (SimpleIdentifier "Color") enumConstDecls- prettyPrint enumDecl `shouldBe` "enum Color\n\- \{\n\- \ red,\n\- \ green,\n\- \ blue\n\- \}"-- it "prints a for loop" $ do- let variableList = VariableDeclarationList Nothing- []- FCVTVar- [VariableDeclaration (SimpleIdentifier "i") (Just (intExp 0))]- condition = BinaryExpression (identExp "i") "<" (intExp 5)- updater = PostfixExpression (identExp "i") "++"- body = (Block' (Block [ ExpressionStatement (- InvocationExpression (- MethodInvocation (Just (identExp "message"))- (SimpleIdentifier "write")- Nothing- (ArgumentList [strLitExp "!"])))]))- forLoop = ForStatement (Just variableList)- Nothing- (Just condition)- [updater]- body- prettyPrint forLoop `shouldBe` "for (var i = 0; i < 5; i++)\n\- \{\n\- \ message.write(\"!\");\n\- \}"-- it "prints a list literal" $ do- let litExp = Literal' . TypedLiteral $ ListLiteral False Nothing [intExp 0, intExp 1, intExp 2]- prettyPrint litExp `shouldBe` "[0, 1, 2]"-- it "prints parameterized types" $ do- let consName = ConstructorName (TypeName (SimpleIdentifier' (SimpleIdentifier "Map"))- (Just (TypeArgumentList [tyName "int", tyName "View"])))- Nothing- let exp = InstanceCreationExpression NCNew consName (ArgumentList [])- prettyPrint exp `shouldBe` "new Map<int, View>()"-- it "prints a switch statement" $ do- let switchMembers = [ SwitchCase [] (strLitExp "CLOSED") [funStmt "executeClosed", (BreakStatement Nothing)]- , SwitchCase [] (strLitExp "PENDING") [funStmt "executePending", (BreakStatement Nothing)]- , SwitchCase [] (strLitExp "APPROVED") [funStmt "executeApproved", (BreakStatement Nothing)]- , SwitchCase [] (strLitExp "DENIED") [funStmt "executeDenied", (BreakStatement Nothing)]- , SwitchCase [] (strLitExp "OPEN") [funStmt "executeOpen", (BreakStatement Nothing)]- , SwitchDefault [] [funStmt "executeUnknown"]- ]- switch = SwitchStatement (identExp "command") switchMembers- prettyPrint switch `shouldBe` "switch (command)\n\- \{\n\- \ case \"CLOSED\":\n\- \ executeClosed();\n\- \ break;\n\- \ case \"PENDING\":\n\- \ executePending();\n\- \ break;\n\- \ case \"APPROVED\":\n\- \ executeApproved();\n\- \ break;\n\- \ case \"DENIED\":\n\- \ executeDenied();\n\- \ break;\n\- \ case \"OPEN\":\n\- \ executeOpen();\n\- \ break;\n\- \ default:\n\- \ executeUnknown();\n\- \}"-- it "prints a try statement" $ do- let arg = Literal' . StringLiteral' . SingleStringLiteral' $- StringInterpolation [ InterpolationString "Error: "- , InterpolationExpression (identExp "e")- ]- try = TryStatement (Block [funStmt "breedMoreLlamas"])- [CatchClause Nothing (SimpleIdentifier "e") Nothing (Block [funStmt1 "print" arg])]- (Just (Block [funStmt "cleanLlamaStalls"]))- prettyPrint try `shouldBe` "try\n\- \{\n\- \ breedMoreLlamas();\n\- \}\n\- \catch (e)\n\- \{\n\- \ print(\"Error: ${e}\");\n\- \}\n\- \finally\n\- \{\n\- \ cleanLlamaStalls();\n\- \}"-- it "prints a constructor" $ do- let varDeclList ty name = VariableDeclarationList Nothing- []- (FCVTType (tyName ty))- [VariableDeclaration (SimpleIdentifier name) Nothing]-- returnType = SimpleIdentifier' (SimpleIdentifier "Point")- consFormals1 = FormalParameterList [ NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "x"))- , NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "y"))- ]- consFormals2 = FormalParameterList [ NormalFormalParameter' (- FieldFormalParameter Nothing- []- (Just (FCVTType (tyName "Map")))- False- (SimpleIdentifier "json"))- ]- methodFormals = FormalParameterList [ NormalFormalParameter' (- FieldFormalParameter Nothing- []- (Just (FCVTType (tyName "Point")))- False- (SimpleIdentifier "other"))- ]- consBody = BlockFunctionBody Sync- (Block [ ExpressionStatement (- AssignmentExpression (identExp "x")- "="- (IndexExpressionForTarget (identExp "json") (strLitExp "x")))- , ExpressionStatement (- AssignmentExpression (identExp "y")- "="- (IndexExpressionForTarget (identExp "json") (strLitExp "y")))- ])- exp1 = BinaryExpression (identExp "x") "-" (PropertyAccess (identExp "other") (SimpleIdentifier "x"))- exp2 = BinaryExpression (identExp "y") "-" (PropertyAccess (identExp "other") (SimpleIdentifier "y"))- methodBody = BlockFunctionBody Sync- (Block [ VariableDeclarationStatement (- VariableDeclarationList Nothing- []- FCVTVar- [VariableDeclaration (SimpleIdentifier "dx") (Just exp1)])- , VariableDeclarationStatement (- VariableDeclarationList Nothing- []- FCVTVar- [VariableDeclaration (SimpleIdentifier "dy") (Just exp2)])- , ReturnStatement (Just (- InvocationExpression (- MethodInvocation Nothing- (SimpleIdentifier "sqrt")- Nothing- (ArgumentList [BinaryExpression (BinaryExpression (identExp "dx") "*" (identExp "dx"))- "+"- (BinaryExpression (identExp "dy") "*" (identExp "dy"))]))))- ])- classMembers = [ FieldDeclaration Nothing [] False (varDeclList "num" "x")- , FieldDeclaration Nothing [] False (varDeclList "num" "y")- , ConstructorDeclaration Nothing [] False False False returnType Nothing consFormals1 [] Nothing Nothing- , ConstructorDeclaration Nothing [] False False False returnType (Just (SimpleIdentifier "fromJson")) consFormals2 [] Nothing (Just consBody)- , MethodDeclaration Nothing [] False Nothing (Just (tyName "num")) Empty False (SimpleIdentifier "distanceTo") Nothing (Just methodFormals) methodBody- ]- clazz = ClassDeclaration Nothing- []- False- (SimpleIdentifier "Point")- Nothing- Nothing- Nothing- Nothing- classMembers- prettyPrint clazz `shouldBe` "class Point\n\- \{\n\- \ num x;\n\- \ num y;\n\- \ Point(this.x, this.y);\n\- \ Point.fromJson(Map json)\n\- \ {\n\- \ x = json[\"x\"];\n\- \ y = json[\"y\"];\n\- \ }\n\- \ num distanceTo(Point other)\n\- \ {\n\- \ var dx = x - other.x;\n\- \ var dy = y - other.y;\n\- \ return sqrt(dx * dx + dy * dy);\n\- \ }\n\- \}"-- it "prints the initializer lists of a constructor" $ do- let varDeclList ty name = VariableDeclarationList Nothing- []- (FCVTType (tyName ty))- [VariableDeclaration (SimpleIdentifier name) Nothing]- returnType = SimpleIdentifier' (SimpleIdentifier "Point")- formals = FormalParameterList [ NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "x"))- , NormalFormalParameter' (FieldFormalParameter Nothing [] Nothing True (SimpleIdentifier "y"))- ]- exp = InvocationExpression (- MethodInvocation Nothing- (SimpleIdentifier "sqrt")- Nothing- (ArgumentList [BinaryExpression (BinaryExpression (identExp "x") "*" (identExp "x"))- "+"- (BinaryExpression (identExp "y") "*" (identExp "y"))]))- classMembers = [ FieldDeclaration Nothing [] False (varDeclList "num" "x")- , FieldDeclaration Nothing [] False (varDeclList "num" "y")- , FieldDeclaration Nothing [] False (varDeclList "num" "distanceFromOrigin")- , ConstructorDeclaration Nothing- []- False- False- False- returnType- Nothing- formals- [ ConstructorFieldInitializer False (SimpleIdentifier "x") (identExp "x")- , ConstructorFieldInitializer False (SimpleIdentifier "y") (identExp "y")- , ConstructorFieldInitializer False (SimpleIdentifier "distanceFromOrigin") exp- ]- Nothing- Nothing- ]- clazz = ClassDeclaration Nothing- []- False- (SimpleIdentifier "Point")- Nothing- Nothing- Nothing- Nothing- classMembers-- prettyPrint clazz `shouldBe` "class Point\n\- \{\n\- \ num x;\n\- \ num y;\n\- \ num distanceFromOrigin;\n\- \ Point(this.x, this.y) : x = x,\n\- \ y = y,\n\- \ distanceFromOrigin = sqrt(x * x + y * y);\n\- \}"-- it "prints the implement clause" $ do- let implements = ImplementsClause [tyName "Comparable", tyName "Location"]- clazz = ClassDeclaration Nothing- []- False- (SimpleIdentifier "Point")- Nothing- Nothing- Nothing- (Just implements)- []- prettyPrint clazz `shouldBe` "class Point implements Comparable, Location\n\- \{\n\- \}"-- it "prints the metadata" $ do- let annotation = Annotation (SimpleIdentifier' (SimpleIdentifier "override")) Nothing Nothing- methodFormals = FormalParameterList [ NormalFormalParameter' (- FieldFormalParameter Nothing- []- (Just (FCVTType (tyName "Invocation")))- False- (SimpleIdentifier "mirror"))- ]- methodDecl = MethodDeclaration Nothing- [annotation]- False- Nothing- (Just (tyName "void"))- Empty- False- (SimpleIdentifier "noSuchMethod")- Nothing- (Just methodFormals)- (BlockFunctionBody Sync (Block []))- prettyPrint methodDecl `shouldBe` "@override\n\- \void noSuchMethod(Invocation mirror)\n\- \{\n\- \}"--main :: IO ()-main = hspec $ do- prettyPrintSpec+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ test/TestHelper.hs view
@@ -0,0 +1,56 @@+module TestHelper where++import Language.Dart.Syntax++intExp :: Integer -> Expression+intExp = Literal' . IntegerLiteral++ident :: String -> Identifier+ident = SimpleIdentifier' . SimpleIdentifier++identExp :: String -> Expression+identExp = Identifier' . ident++tyName :: String -> TypeName+tyName name = TypeName (ident name) Nothing++strType = tyName "String"+numType = tyName "num"++formal :: TypeName -> String -> FormalParameter+formal ty p = NormalFormalParameter' $+ SimpleFormalParameter Nothing [] (Just (FVTType ty)) (SimpleIdentifier p)++posFormal :: TypeName -> String -> FormalParameter+posFormal ty p = DefaultFormalParameter parameter Positional Nothing+ where parameter = (SimpleFormalParameter Nothing [] (Just (FVTType ty)) (SimpleIdentifier p))++var :: String -> FormalParameter+var p = NormalFormalParameter' $+ SimpleFormalParameter Nothing [] (Just FVTVar) (SimpleIdentifier p)++strLit :: String -> StringLiteral+strLit = SingleStringLiteral' . SimpleStringLiteral++strLitExp :: String -> Expression+strLitExp = Literal' . StringLiteral' . strLit++nullExp :: Expression+nullExp = Literal' NullLiteral++funStmt :: String -> Statement+funStmt name = ExpressionStatement (+ InvocationExpression (+ MethodInvocation Nothing+ (SimpleIdentifier name)+ Nothing+ (ArgumentList [])))++funStmt1 :: String -> Expression -> Statement+funStmt1 name arg1 = ExpressionStatement (+ InvocationExpression (+ MethodInvocation Nothing+ (SimpleIdentifier name)+ Nothing+ (ArgumentList [arg1])))+