2017-04-21 01:13:28 +03:00
|
|
|
module CommandSpec where
|
2017-03-01 01:55:57 +03:00
|
|
|
|
2017-04-04 00:39:04 +03:00
|
|
|
import Command
|
2017-03-01 02:00:56 +03:00
|
|
|
import Data.Aeson
|
2017-04-21 23:56:19 +03:00
|
|
|
import Data.Functor.Both as Both
|
2017-05-30 18:33:23 +03:00
|
|
|
import Data.Map as Map
|
2017-04-04 00:39:04 +03:00
|
|
|
import Data.Maybe
|
2017-04-21 01:13:28 +03:00
|
|
|
import Data.String
|
2017-05-10 01:49:38 +03:00
|
|
|
import Language
|
2017-04-21 01:13:28 +03:00
|
|
|
import Prologue hiding (readFile, toList)
|
2017-04-04 03:09:02 +03:00
|
|
|
import qualified Git.Types as Git
|
|
|
|
import Renderer hiding (errors)
|
|
|
|
import Source
|
2017-04-21 20:25:47 +03:00
|
|
|
import Semantic
|
2017-05-30 16:58:16 +03:00
|
|
|
import Semantic.Task
|
2017-03-01 01:55:57 +03:00
|
|
|
import Test.Hspec hiding (shouldBe, shouldNotBe, shouldThrow, errorCall)
|
|
|
|
import Test.Hspec.Expectations.Pretty
|
|
|
|
|
|
|
|
spec :: Spec
|
|
|
|
spec = parallel $ do
|
2017-04-21 01:13:28 +03:00
|
|
|
describe "readFile" $ do
|
|
|
|
it "returns a blob for extant files" $ do
|
2017-05-11 20:10:48 +03:00
|
|
|
blob <- runCommand (readFile "semantic-diff.cabal" Nothing)
|
2017-04-21 20:25:47 +03:00
|
|
|
path blob `shouldBe` "semantic-diff.cabal"
|
2017-04-21 01:13:28 +03:00
|
|
|
|
2017-04-21 20:25:47 +03:00
|
|
|
it "returns a nullBlob for absent files" $ do
|
2017-05-11 20:10:48 +03:00
|
|
|
blob <- runCommand (readFile "this file should not exist" Nothing)
|
2017-04-21 20:25:47 +03:00
|
|
|
nullBlob blob `shouldBe` True
|
2017-04-21 01:13:28 +03:00
|
|
|
|
2017-05-17 22:53:05 +03:00
|
|
|
describe "readBlobPairsFromHandle" $ do
|
2017-05-23 21:00:20 +03:00
|
|
|
let a = sourceBlob "method.rb" (Just Ruby) "def foo; end"
|
|
|
|
let b = sourceBlob "method.rb" (Just Ruby) "def bar(x); end"
|
2017-05-17 22:47:45 +03:00
|
|
|
it "returns blobs for valid JSON encoded diff input" $ do
|
2017-05-23 21:00:20 +03:00
|
|
|
blobs <- blobsFromFilePath "test/fixtures/input/diff.json"
|
2017-05-17 22:47:45 +03:00
|
|
|
blobs `shouldBe` [both a b]
|
|
|
|
|
2017-05-23 21:00:20 +03:00
|
|
|
it "returns blobs when there's no before" $ do
|
|
|
|
blobs <- blobsFromFilePath "test/fixtures/input/diff-no-before.json"
|
|
|
|
blobs `shouldBe` [both (emptySourceBlob "method.rb") b]
|
|
|
|
|
|
|
|
it "returns blobs when there's null before" $ do
|
|
|
|
blobs <- blobsFromFilePath "test/fixtures/input/diff-null-before.json"
|
|
|
|
blobs `shouldBe` [both (emptySourceBlob "method.rb") b]
|
|
|
|
|
|
|
|
it "returns blobs when there's no after" $ do
|
|
|
|
blobs <- blobsFromFilePath "test/fixtures/input/diff-no-after.json"
|
|
|
|
blobs `shouldBe` [both a (emptySourceBlob "method.rb")]
|
|
|
|
|
|
|
|
it "returns blobs when there's null after" $ do
|
|
|
|
blobs <- blobsFromFilePath "test/fixtures/input/diff-null-after.json"
|
|
|
|
blobs `shouldBe` [both a (emptySourceBlob "method.rb")]
|
|
|
|
|
|
|
|
|
2017-05-19 00:04:44 +03:00
|
|
|
it "returns blobs for unsupported language" $ do
|
|
|
|
h <- openFile "test/fixtures/input/diff-unsupported-language.json" ReadMode
|
|
|
|
blobs <- runCommand (readBlobPairsFromHandle h)
|
2017-05-23 21:00:20 +03:00
|
|
|
let b' = sourceBlob "test.kt" Nothing "fun main(args: Array<String>) {\nprintln(\"hi\")\n}\n"
|
|
|
|
blobs `shouldBe` [both (emptySourceBlob "test.kt") b']
|
2017-05-19 00:04:44 +03:00
|
|
|
|
|
|
|
it "detects language based on filepath for empty language" $ do
|
2017-05-23 21:00:20 +03:00
|
|
|
blobs <- blobsFromFilePath "test/fixtures/input/diff-empty-language.json"
|
2017-05-19 00:04:44 +03:00
|
|
|
blobs `shouldBe` [both a b]
|
|
|
|
|
|
|
|
it "throws on blank input" $ do
|
2017-05-17 22:47:45 +03:00
|
|
|
h <- openFile "test/fixtures/input/blank.json" ReadMode
|
2017-05-17 22:53:05 +03:00
|
|
|
runCommand (readBlobPairsFromHandle h) `shouldThrow` (== ExitFailure 1)
|
2017-05-17 22:47:45 +03:00
|
|
|
|
2017-05-19 00:04:44 +03:00
|
|
|
it "throws if language field not given" $ do
|
|
|
|
h <- openFile "test/fixtures/input/diff-no-language.json" ReadMode
|
|
|
|
runCommand (readBlobsFromHandle h) `shouldThrow` (== ExitFailure 1)
|
|
|
|
|
2017-05-17 23:34:09 +03:00
|
|
|
describe "readBlobsFromHandle" $ do
|
|
|
|
it "returns blobs for valid JSON encoded parse input" $ do
|
|
|
|
h <- openFile "test/fixtures/input/parse.json" ReadMode
|
|
|
|
blobs <- runCommand (readBlobsFromHandle h)
|
2017-05-19 00:04:44 +03:00
|
|
|
let a = sourceBlob "method.rb" (Just Ruby) "def foo; end"
|
2017-05-17 23:34:09 +03:00
|
|
|
blobs `shouldBe` [a]
|
|
|
|
|
2017-05-19 00:04:44 +03:00
|
|
|
it "throws on blank input" $ do
|
2017-05-17 23:34:09 +03:00
|
|
|
h <- openFile "test/fixtures/input/blank.json" ReadMode
|
|
|
|
runCommand (readBlobsFromHandle h) `shouldThrow` (== ExitFailure 1)
|
|
|
|
|
2017-04-21 23:56:19 +03:00
|
|
|
describe "readFilesAtSHA" $ do
|
|
|
|
it "returns blobs for the specified paths" $ do
|
2017-05-10 01:49:38 +03:00
|
|
|
blobs <- runCommand (readFilesAtSHA repoPath [] [("methods.rb", Just Ruby)] (Both.snd (shas methodsFixture)))
|
2017-04-21 23:56:19 +03:00
|
|
|
blobs `shouldBe` [methodsBlob]
|
|
|
|
|
|
|
|
it "returns emptySourceBlob if path doesn't exist at sha" $ do
|
2017-05-10 01:49:38 +03:00
|
|
|
blobs <- runCommand (readFilesAtSHA repoPath [] [("methods.rb", Just Ruby)] (Both.fst (shas methodsFixture)))
|
2017-04-21 23:56:19 +03:00
|
|
|
nonExistentBlob <$> blobs `shouldBe` [True]
|
|
|
|
|
2017-04-21 01:13:28 +03:00
|
|
|
describe "readFilesAtSHAs" $ do
|
|
|
|
it "returns blobs for the specified paths" $ do
|
2017-05-10 01:49:38 +03:00
|
|
|
blobs <- runCommand (readFilesAtSHAs repoPath [] [("methods.rb", Just Ruby)] (shas methodsFixture))
|
2017-04-21 01:13:28 +03:00
|
|
|
blobs `shouldBe` expectedBlobs methodsFixture
|
|
|
|
|
|
|
|
it "returns blobs for all paths if none are specified" $ do
|
|
|
|
blobs <- runCommand (readFilesAtSHAs repoPath [] [] (shas methodsFixture))
|
|
|
|
blobs `shouldBe` expectedBlobs methodsFixture
|
|
|
|
|
|
|
|
it "returns entries for missing paths" $ do
|
2017-05-10 01:49:38 +03:00
|
|
|
blobs <- runCommand (readFilesAtSHAs repoPath [] [("this file should not exist", Nothing)] (shas methodsFixture))
|
2017-04-21 20:25:47 +03:00
|
|
|
let b = emptySourceBlob "this file should not exist"
|
|
|
|
blobs `shouldBe` [both b b]
|
2017-04-21 01:13:28 +03:00
|
|
|
|
2017-03-01 02:00:56 +03:00
|
|
|
describe "fetchDiffs" $ do
|
|
|
|
it "generates toc summaries for two shas" $ do
|
2017-05-30 18:11:04 +03:00
|
|
|
Summaries summaries errors <- fetchDiffsOutput "test/fixtures/git/examples/all-languages.git" "dfac8fd681b0749af137aebf3203e77a06fbafc2" "2e4144eb8c44f007463ec34cb66353f0041161fe" [("methods.rb", Just Ruby)]
|
2017-05-30 16:58:16 +03:00
|
|
|
errors `shouldBe` fromList []
|
2017-05-30 18:33:23 +03:00
|
|
|
summaries `shouldBe` fromList [("methods.rb", [methodsObject])]
|
2017-03-01 02:00:56 +03:00
|
|
|
|
|
|
|
it "generates toc summaries for two shas inferring paths" $ do
|
2017-05-30 18:11:04 +03:00
|
|
|
Summaries summaries errors <- fetchDiffsOutput "test/fixtures/git/examples/all-languages.git" "dfac8fd681b0749af137aebf3203e77a06fbafc2" "2e4144eb8c44f007463ec34cb66353f0041161fe" []
|
2017-05-30 16:58:16 +03:00
|
|
|
errors `shouldBe` fromList []
|
2017-05-30 18:33:23 +03:00
|
|
|
summaries `shouldBe` fromList [("methods.rb", [methodsObject])]
|
2017-03-01 02:00:56 +03:00
|
|
|
|
|
|
|
it "errors with bad shas" $
|
2017-05-30 18:11:04 +03:00
|
|
|
fetchDiffsOutput "test/fixtures/git/examples/all-languages.git" "dead" "beef" [("methods.rb", Just Ruby)]
|
2017-03-01 02:00:56 +03:00
|
|
|
`shouldThrow` (== Git.BackendError "Could not lookup dead: Object not found - no match for prefix (dead000000000000000000000000000000000000)")
|
|
|
|
|
|
|
|
it "errors with bad repo path" $
|
2017-05-30 18:11:04 +03:00
|
|
|
fetchDiffsOutput "test/fixtures/git/examples/not-a-repo.git" "dfac8fd681b0749af137aebf3203e77a06fbafc2" "2e4144eb8c44f007463ec34cb66353f0041161fe" [("methods.rb", Just Ruby)]
|
2017-03-01 02:00:56 +03:00
|
|
|
`shouldThrow` errorCall "Could not open repository \"test/fixtures/git/examples/not-a-repo.git\""
|
|
|
|
|
2017-04-21 01:13:28 +03:00
|
|
|
where repoPath = "test/fixtures/git/examples/all-languages.git"
|
|
|
|
methodsFixture = Fixture
|
|
|
|
(both "dfac8fd681b0749af137aebf3203e77a06fbafc2" "2e4144eb8c44f007463ec34cb66353f0041161fe")
|
2017-04-21 20:25:47 +03:00
|
|
|
[ both (emptySourceBlob "methods.rb") methodsBlob ]
|
2017-05-10 01:49:38 +03:00
|
|
|
methodsBlob = SourceBlob (Source "def foo\nend\n") "ff7bbbe9495f61d9e1e58c597502d152bab1761e" "methods.rb" (Just defaultPlainBlob) (Just Ruby)
|
2017-05-30 18:33:23 +03:00
|
|
|
methodsObject = object [ "span" .= object [ "start" .= [ 1, 1 :: Int ], "end" .= [ 2, 4 :: Int ] ], "category" .= ("Method" :: Text), "term" .= ("foo" :: Text), "changeType" .= ("added" :: Text) ]
|
2017-05-23 21:00:20 +03:00
|
|
|
blobsFromFilePath path = do
|
|
|
|
h <- openFile path ReadMode
|
|
|
|
blobs <- runCommand (readBlobPairsFromHandle h)
|
|
|
|
pure blobs
|
2017-04-21 01:13:28 +03:00
|
|
|
|
2017-04-21 20:25:47 +03:00
|
|
|
data Fixture = Fixture { shas :: Both String, expectedBlobs :: [Both SourceBlob] }
|
2017-04-21 01:13:28 +03:00
|
|
|
|
2017-05-30 18:11:04 +03:00
|
|
|
fetchDiffsOutput :: FilePath -> String -> String -> [(FilePath, Maybe Language)] -> IO Summaries
|
|
|
|
fetchDiffsOutput gitDir sha1 sha2 filePaths = do
|
2017-05-30 16:58:16 +03:00
|
|
|
blobPairs <- runCommand $ readFilesAtSHAs gitDir [] filePaths (both sha1 sha2)
|
2017-05-30 17:25:22 +03:00
|
|
|
fromMaybe mempty <$> runTask (distributeFoldMap (Semantic.parseDiffAndRenderBlobPair Renderer.ToCDiffRenderer) blobPairs)
|