1
1
mirror of https://github.com/github/semantic.git synced 2024-11-28 10:15:55 +03:00
semantic/semantic-python/test-graphing/GraphTest.hs
2020-02-05 18:03:53 -05:00

158 lines
5.4 KiB
Haskell
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Main (main) where
import Analysis.Name (Name)
import qualified Analysis.Name as Name
import Control.Algebra
import Control.Carrier.Lift
import Control.Carrier.Sketch.Fresh
import Control.Monad
import qualified Data.ByteString as ByteString
import qualified Data.ScopeGraph as ScopeGraph
import qualified Language.Python ()
import qualified Language.Python as Py (Term)
import ScopeGraph.Convert
import Source.Loc
import qualified Source.Source as Source
import System.Exit (die)
import System.Path ((</>))
import qualified System.Path as Path
import qualified System.Path.Directory as Path
import qualified Test.Tasty as Tasty
import qualified Test.Tasty.HUnit as HUnit
import qualified TreeSitter.Python as TSP
import qualified TreeSitter.Unmarshal as TS
{-
The Python code here is
hello = ()
goodbye = ()
The graph should be
🏁
|
1----"hello"
|
|
|
|
2----"goodbye"
-}
runScopeGraph :: ToScopeGraph t => Path.AbsRelFile -> Source.Source -> t Loc -> (ScopeGraph.ScopeGraph Name, Result)
runScopeGraph p _src item = run . runSketch (Just p) $ scopeGraph item
sampleGraphThing :: (Has Sketch sig m) => m Result
sampleGraphThing = do
declare "hello" (DeclProperties ScopeGraph.Assignment ScopeGraph.Default Nothing)
declare "goodbye" (DeclProperties ScopeGraph.Assignment ScopeGraph.Default Nothing)
pure Complete
graphFile :: FilePath -> IO (ScopeGraph.ScopeGraph Name, Result)
graphFile fp = do
file <- ByteString.readFile fp
tree <- TS.parseByteString @Py.Term @Loc TSP.tree_sitter_python file
pyModule <- either die pure tree
pure $ runScopeGraph (Path.absRel fp) (Source.fromUTF8 file) pyModule
assertSimpleAssignment :: HUnit.Assertion
assertSimpleAssignment = do
let path = "semantic-python/test/fixtures/1-04-toplevel-assignment.py"
(result, Complete) <- graphFile path
(expecto, Complete) <- runM $ runSketch Nothing sampleGraphThing
HUnit.assertEqual "Should work for simple case" expecto result
expectedReference :: (Has Sketch sig m) => m Result
expectedReference = do
declare "x" (DeclProperties ScopeGraph.Assignment ScopeGraph.Default Nothing)
reference "x" "x" RefProperties
pure Complete
assertSimpleReference :: HUnit.Assertion
assertSimpleReference = do
let path = "semantic-python/test/fixtures/5-01-simple-reference.py"
(result, Complete) <- graphFile path
(expecto, Complete) <- runM $ runSketch Nothing expectedReference
HUnit.assertEqual "Should work for simple case" expecto result
expectedLexicalScope :: (Has Sketch sig m) => m Result
expectedLexicalScope = do
_ <- declareFunction (Just $ Name.name "foo") (FunProperties ScopeGraph.Function)
reference "foo" "foo" RefProperties {}
pure Complete
expectedFunctionArg :: (Has Sketch sig m) => m Result
expectedFunctionArg = do
(_, associatedScope) <- declareFunction (Just $ Name.name "foo") (FunProperties ScopeGraph.Function)
withScope associatedScope $ do
declare "x" (DeclProperties ScopeGraph.Identifier ScopeGraph.Default Nothing)
reference "x" "x" RefProperties
pure ()
reference "foo" "foo" RefProperties
pure Complete
expectedImportHole :: (Has Sketch sig m) => m Result
expectedImportHole = do
addImportEdge Import ["cheese", "ints"]
assertLexicalScope :: HUnit.Assertion
assertLexicalScope = do
let path = "semantic-python/test/fixtures/5-02-simple-function.py"
(graph, _) <- graphFile path
case run (runSketch Nothing expectedLexicalScope) of
(expecto, Complete) -> HUnit.assertEqual "Should work for simple case" expecto graph
(_, Todo msg) -> HUnit.assertFailure ("Failed to complete:" <> show msg)
assertFunctionArg :: HUnit.Assertion
assertFunctionArg = do
let path = "semantic-python/test/fixtures/5-03-function-argument.py"
(graph, _) <- graphFile path
case run (runSketch Nothing expectedFunctionArg) of
(expecto, Complete) -> HUnit.assertEqual "Should work for simple case" expecto graph
(_, Todo msg) -> HUnit.assertFailure ("Failed to complete:" <> show msg)
assertImportHole :: HUnit.Assertion
assertImportHole = do
let path = "semantic-python/test/fixtures/cheese/6-01-imports.py"
(graph, _) <- graphFile path
case run (runSketch Nothing expectedImportHole) of
(expecto, Complete) -> HUnit.assertEqual "Should work for simple case" expecto graph
(_, Todo msg) -> HUnit.assertFailure ("Failed to complete:" <> show msg)
main :: IO ()
main = do
-- make sure we're in the root directory so the paths resolve properly
cwd <- Path.getCurrentDirectory
when (Path.takeDirName cwd == Just (Path.relDir "semantic-python"))
(Path.setCurrentDirectory (cwd </> Path.relDir ".."))
Tasty.defaultMain $
Tasty.testGroup "Tests" [
Tasty.testGroup "declare" [
HUnit.testCase "toplevel assignment" assertSimpleAssignment
],
Tasty.testGroup "reference" [
HUnit.testCase "simple reference" assertSimpleReference
],
Tasty.testGroup "lexical scopes" [
HUnit.testCase "simple function scope" assertLexicalScope
, HUnit.testCase "simple function argument" assertFunctionArg
],
Tasty.testGroup "imports" [
HUnit.testCase "simple function argument" assertImportHole
]
]