1
1
mirror of https://github.com/github/semantic.git synced 2024-11-24 00:42:33 +03:00
semantic/test/Integration/Spec.hs

101 lines
4.1 KiB
Haskell
Raw Normal View History

2019-06-12 18:04:42 +03:00
{-# LANGUAGE ImplicitParams, LambdaCase, NamedFieldPuns #-}
2019-06-20 00:56:37 +03:00
module Integration.Spec (testTree) where
import Control.Exception (throw)
2019-06-12 20:16:34 +03:00
import Data.Foldable (find)
2017-04-03 23:34:25 +03:00
import Data.List (union, concat, transpose)
2019-06-12 18:04:42 +03:00
import qualified Data.ByteString.Lazy as BL
import System.FilePath.Glob
2019-06-12 18:04:42 +03:00
import System.IO.Unsafe
2018-03-13 21:04:58 +03:00
import SpecHelpers hiding ((</>))
import qualified System.Path as Path
import System.Path ((</>))
2019-06-12 18:04:42 +03:00
import Test.Tasty
import Test.Tasty.Golden
languages :: [Path.RelDir]
languages = fmap Path.relDir ["go", "javascript", "json", "python", "ruby", "typescript", "tsx"]
2018-03-13 21:10:50 +03:00
2019-06-20 00:56:37 +03:00
testTree :: (?session :: TaskSession) => TestTree
testTree = testGroup "Integration (golden tests)" $ fmap testsForLanguage languages
testsForLanguage :: (?session :: TaskSession) => Path.RelDir -> TestTree
2019-06-12 18:04:42 +03:00
testsForLanguage language = do
let dir = Path.relDir "test/fixtures" </> language </> Path.relDir "corpus"
2019-06-12 18:04:42 +03:00
let items = unsafePerformIO (examples dir)
localOption (mkTimeout 3000000) $ testGroup (Path.toString language) $ fmap testForExample items
{-# NOINLINE testsForLanguage #-}
data Example = DiffExample { fileA :: Path.RelFile, fileB :: Path.RelFile, diffOutput :: Path.RelFile }
| ParseExample { file :: Path.RelFile, parseOutput :: Path.RelFile }
2017-02-22 03:30:39 +03:00
deriving (Eq, Show)
2019-06-12 18:04:42 +03:00
testForExample :: (?session :: TaskSession) => Example -> TestTree
testForExample = \case
DiffExample{fileA, fileB, diffOutput} ->
goldenVsStringDiff
("diffs " <> Path.toString diffOutput)
2019-06-12 18:04:42 +03:00
(\ref new -> ["git", "diff", ref, new])
(Path.toString diffOutput)
(BL.fromStrict <$> diffFilePaths ?session (Both (Path.toString fileA) (Path.toString fileB)))
ParseExample{file, parseOutput} ->
goldenVsStringDiff
("parses " <> Path.toString parseOutput)
(\ref new -> ["git", "diff", ref, new])
(Path.toString parseOutput)
(parseFilePath ?session (Path.toString file) >>= either throw (pure . BL.fromStrict))
2019-06-12 18:04:42 +03:00
-- | Return all the examples from the given directory. Examples are expected to
2017-02-22 19:32:19 +03:00
-- | have the form:
-- |
2017-02-23 01:07:47 +03:00
-- | example-name.A.rb - The left hand side of the diff.
-- | example-name.B.rb - The right hand side of the diff.
2017-02-22 03:05:08 +03:00
-- |
2017-02-23 01:07:47 +03:00
-- | example-name.diffA-B.txt - The expected sexpression diff output for A -> B.
-- | example-name.diffB-A.txt - The expected sexpression diff output for B -> A.
2017-02-22 03:05:08 +03:00
-- |
2017-02-23 01:07:47 +03:00
-- | example-name.parseA.txt - The expected sexpression parse tree for example-name.A.rb
-- | example-name.parseB.txt - The expected sexpression parse tree for example-name.B.rb
examples :: Path.RelDir -> IO [Example]
examples directory = do
as <- globFor "*.A.*"
bs <- globFor "*.B.*"
sExpAs <- globFor "*.parseA.txt"
sExpBs <- globFor "*.parseB.txt"
sExpDiffsAB <- globFor "*.diffA-B.txt"
sExpDiffsBA <- globFor "*.diffB-A.txt"
let exampleDiff lefts rights out name = DiffExample (lookupNormalized name lefts) (lookupNormalized name rights) out
2017-02-23 01:07:47 +03:00
let exampleParse files out name = ParseExample (lookupNormalized name files) out
let keys = (normalizeName <$> as) `union` (normalizeName <$> bs)
pure $ merge [ getExamples (exampleParse as) sExpAs keys
, getExamples (exampleParse bs) sExpBs keys
, getExamples (exampleDiff as bs) sExpDiffsAB keys
, getExamples (exampleDiff bs as) sExpDiffsBA keys ]
where
merge = concat . transpose
2017-02-23 01:07:47 +03:00
-- Only returns examples if they exist
getExamples f list = foldr (go f list) []
where go f list name acc = case lookupNormalized' name list of
Just out -> f out name : acc
Nothing -> acc
lookupNormalized :: Path.RelFile -> [Path.RelFile] -> Path.RelFile
2017-02-22 03:05:08 +03:00
lookupNormalized name xs = fromMaybe
(error ("cannot find " <> Path.toString name <> " make sure .A, .B and exist."))
2017-02-23 01:07:47 +03:00
(lookupNormalized' name xs)
lookupNormalized' :: Path.RelFile -> [Path.RelFile] -> Maybe Path.RelFile
2017-02-23 01:07:47 +03:00
lookupNormalized' name = find ((== name) . normalizeName)
globFor :: String -> IO [Path.RelFile]
globFor p = fmap Path.relFile <$> globDir1 (compile p) (Path.toString directory)
2017-02-22 03:05:08 +03:00
-- | Given a test name like "foo.A.js", return "foo".
normalizeName :: Path.RelFile -> Path.RelFile
normalizeName = Path.dropExtension . Path.dropExtension