Permalink
Browse files

Added beginnings of testing framework via round trip

  • Loading branch information...
bjpop committed Mar 13, 2011
1 parent 2806d6e commit 0094615775b8ae49ed2c086364e55ba18b37ba7b
Showing with 88 additions and 0 deletions.
  1. +30 −0 docs/notes.txt
  2. +4 −0 language-python.cabal
  3. +54 −0 test/RoundTrip.hs
View
@@ -0,0 +1,30 @@
+Notes about the development of language-python
+----------------------------------------------
+
+Testing
+-------
+
+How to test the parser? What to test for?
+
+Idea: round trip parsing:
+
+ parseAndPrint < test.py > out_1.py
+
+It may not be the case that test.py == out_1.py, using string equality on the
+contents of the python files. Even the ASTs might be different (eg
+parenthesising, line numbers).
+
+So we run printAndParse on the output:
+
+ parseAndPrint < out_1.py > out_2.py
+
+Hypothesis: out_1.py and out_2.py will be identical source files: we've
+reached a fixed point. If they are not equal then there is a bug in either
+the parser or the pretty printer or both.
+
+Issues: this combines testing of the parser and pretty printer. It may
+be desirable to test them in isolation - but is it worth the extra
+effort?
+
+It is harder to test the parser in isolation because its output is an
+AST. Constructing expected ASTs is tedious, even for small programs.
View
@@ -19,6 +19,10 @@ extra-source-files: src/Language/Python/Version3/Parser/Parser.y
ghc_6_12-13/Language/Python/Common/AST.hs
ghc_normal/Language/Python/Common/AST.hs
+flag test
+ description: Build testsuite
+ default: False
+
Library
-- work around the memory usage bug in ghc 6.12.x
if impl(ghc < 6.12) || impl(ghc >= 6.14)
View
@@ -0,0 +1,54 @@
+import Language.Python.Common
+import Language.Python.Version2 as V2
+import Language.Python.Version3 as V3
+import System.Exit
+
+data PythonVersion = Two | Three
+ deriving (Eq, Show)
+
+version = Two
+
+main :: IO ()
+main = do
+ args <- getArgs
+ case args of
+ (versionStr:inFile:_rest) -> do
+ let version = parseVersion versionStr
+ parser = if version == Two then V2.parseModule else V3.parseModule
+ contents <- readFile inFile
+ pretty1 <- parseAndPretty parser inFile contents
+ pretty2 <- parseAndPretty parser "<pretty printed>" pretty1
+ if pretty1 == pretty2
+ then do
+ putStrLn "Round trip parse succeeded"
+ else do
+ doubleLine
+ putStrLn "Round trip parse failed"
+ doubleLine
+ putStrLn "pretty1"
+ line
+ putStrLn pretty1
+ doubleLine
+ putStrLn "pretty2"
+ line
+ putStrLn pretty2
+ exitFailure
+ other ->
+ putStrLn "Incorrect command line. Expected: pythonVersion inputFileName"
+
+line, doubleLine :: IO ()
+line = putStrLn $ replicate 80 '-'
+doubleLine = putStrLn $ replicate 80 '='
+
+parseAndPretty parser fileName contents =
+ case parser contents fileName of
+ Left e -> do
+ putStrLn "Parse failed with error:"
+ putStrLn $ prettyText e
+ exitFailure
+ Right (ast, _comments) -> do
+ return $ prettyText ast ++ "\n"
+
+parseVersion :: String -> PythonVersion
+parseVersion "2" = Two
+parseVersion "3" = Three

0 comments on commit 0094615

Please sign in to comment.