module Semantic.IO.Spec (spec) where import Prelude hiding (readFile) import Control.Monad.IO.Class import Data.List import System.Directory import System.Exit (ExitCode (..)) import System.IO.Temp import System.Process import Data.Blob import Data.Handle import SpecHelpers hiding (readFile) import qualified Semantic.Git as Git spec :: Spec spec = parallel $ do describe "readBlobsFromGitRepo" $ do hasGit <- runIO $ isJust <$> findExecutable "git" when hasGit . it "should read from a git directory" $ do -- This temporary directory will be cleaned after use. blobs <- liftIO . withSystemTempDirectory "semantic-temp-git-repo" $ \dir -> do let commands = [ "cd " <> dir , "git init" , "touch foo.py bar.rb" , "git add foo.py bar.rb" , "git config user.name 'Test'" , "git config user.email 'test@test.test'" , "git commit -am 'test commit'" ] exit <- system (intercalate " && " commands) when (exit /= ExitSuccess) (fail ("Couldn't run git properly in dir " <> dir)) readBlobsFromGitRepo (dir ".git") (Git.OID "HEAD") [] let files = sortOn fileLanguage (blobFile <$> blobs) files `shouldBe` [ File "foo.py" Python , File "bar.rb" Ruby ] describe "readFile" $ do it "returns a blob for extant files" $ do Just blob <- readBlobFromFile (File "semantic.cabal" Unknown) blobPath blob `shouldBe` "semantic.cabal" it "throws for absent files" $ do readBlobFromFile (File "this file should not exist" Unknown) `shouldThrow` anyIOException describe "readBlobPairsFromHandle" $ do let a = sourceBlob "method.rb" Ruby "def foo; end" let b = sourceBlob "method.rb" Ruby "def bar(x); end" it "returns blobs for valid JSON encoded diff input" $ do putStrLn "step 1" blobs <- blobsFromFilePath "test/fixtures/cli/diff.json" putStrLn "done" blobs `shouldBe` [Diffing a b] it "returns blobs when there's no before" $ do blobs <- blobsFromFilePath "test/fixtures/cli/diff-no-before.json" blobs `shouldBe` [Inserting b] it "returns blobs when there's null before" $ do blobs <- blobsFromFilePath "test/fixtures/cli/diff-null-before.json" blobs `shouldBe` [Inserting b] it "returns blobs when there's no after" $ do blobs <- blobsFromFilePath "test/fixtures/cli/diff-no-after.json" blobs `shouldBe` [Deleting a] it "returns blobs when there's null after" $ do blobs <- blobsFromFilePath "test/fixtures/cli/diff-null-after.json" blobs `shouldBe` [Deleting a] it "returns blobs for unsupported language" $ do h <- openFileForReading "test/fixtures/cli/diff-unsupported-language.json" blobs <- readBlobPairsFromHandle h let b' = sourceBlob "test.kt" Unknown "fun main(args: Array) {\nprintln(\"hi\")\n}\n" blobs `shouldBe` [Inserting b'] it "detects language based on filepath for empty language" $ do blobs <- blobsFromFilePath "test/fixtures/cli/diff-empty-language.json" blobs `shouldBe` [Diffing a b] it "throws on blank input" $ do h <- openFileForReading "test/fixtures/cli/blank.json" readBlobPairsFromHandle h `shouldThrow` (== ExitFailure 1) it "throws if language field not given" $ do h <- openFileForReading "test/fixtures/cli/diff-no-language.json" readBlobsFromHandle h `shouldThrow` (== ExitFailure 1) it "throws if null on before and after" $ do h <- openFileForReading "test/fixtures/cli/diff-null-both-sides.json" readBlobPairsFromHandle h `shouldThrow` (== ExitFailure 1) describe "readBlobsFromHandle" $ do it "returns blobs for valid JSON encoded parse input" $ do h <- openFileForReading "test/fixtures/cli/parse.json" blobs <- readBlobsFromHandle h let a = sourceBlob "method.rb" Ruby "def foo; end" blobs `shouldBe` [a] it "throws on blank input" $ do h <- openFileForReading "test/fixtures/cli/blank.json" readBlobsFromHandle h `shouldThrow` (== ExitFailure 1) where blobsFromFilePath path = do h <- openFileForReading path putStrLn "got handle" blobs <- readBlobPairsFromHandle h putStrLn "got blobs" pure blobs