1
1
mirror of https://github.com/github/semantic.git synced 2024-12-01 09:15:01 +03:00
semantic/test/CorpusSpec.hs

89 lines
4.1 KiB
Haskell
Raw Normal View History

2016-02-16 20:33:41 +03:00
module CorpusSpec where
2016-02-17 00:38:31 +03:00
import Diffing
2016-02-17 23:54:37 +03:00
import Renderer
2016-02-26 00:19:33 +03:00
import qualified Renderer.JSON as J
2016-02-25 23:32:39 +03:00
import qualified Renderer.Patch as P
import qualified Renderer.Split as Split
2016-02-17 00:38:31 +03:00
2016-02-18 01:42:27 +03:00
import Control.DeepSeq
import Data.Functor.Both
2016-03-01 04:52:30 +03:00
import qualified Data.ByteString.Lazy.Char8 as B
2016-02-17 00:38:31 +03:00
import Data.List as List
import Data.Map as Map
2016-02-18 01:10:04 +03:00
import Data.Maybe
2016-02-17 00:38:31 +03:00
import Data.Set as Set
2016-02-17 23:54:37 +03:00
import qualified Data.Text as T
2016-02-18 00:06:24 +03:00
import qualified Data.Text.Lazy as TL
2016-03-01 03:39:04 +03:00
import Prelude hiding (fst, snd)
import qualified Prelude
import qualified Source as S
2016-02-17 00:38:31 +03:00
import System.FilePath
import System.FilePath.Glob
2016-02-16 20:33:41 +03:00
import Test.Hspec
spec :: Spec
2016-02-18 01:43:59 +03:00
spec = parallel $ do
describe "crashers crash" $ runTestsIn "test/crashers-todo/" $ \ a b -> a `deepseq` return (a == b) `shouldThrow` anyException
2016-02-29 06:18:44 +03:00
describe "crashers should not crash" $ runTestsIn "test/crashers/" shouldBe
describe "todos are incorrect" $ runTestsIn "test/diffs-todo/" shouldNotBe
describe "should produce the correct diff" $ runTestsIn "test/diffs/" shouldBe
2016-02-17 00:38:31 +03:00
2016-02-17 20:54:42 +03:00
it "lists example fixtures" $ do
2016-02-17 00:38:31 +03:00
examples "test/crashers/" `shouldNotReturn` []
2016-02-17 20:54:42 +03:00
examples "test/diffs/" `shouldNotReturn` []
2016-02-17 00:38:31 +03:00
where
2016-02-29 06:18:44 +03:00
runTestsIn :: String -> (String -> String -> Expectation) -> SpecWith ()
2016-02-22 22:38:49 +03:00
runTestsIn directory matcher = do
2016-02-18 01:10:04 +03:00
paths <- runIO $ examples directory
let tests = correctTests =<< paths
2016-03-01 03:39:04 +03:00
mapM_ (\ (formatName, renderer, paths, output) -> it (normalizeName (fst paths) ++ " (" ++ formatName ++ ")") $ testDiff renderer paths output matcher) tests
2016-02-18 01:10:04 +03:00
correctTests :: (Both FilePath, Maybe FilePath, Maybe FilePath, Maybe FilePath) -> [(String, Renderer a String, Both FilePath, Maybe FilePath)]
correctTests paths@(_, Nothing, Nothing, Nothing) = testsForPaths paths
correctTests paths = List.filter (\(_, _, _, output) -> isJust output) $ testsForPaths paths
testsForPaths :: (Both FilePath, Maybe FilePath, Maybe FilePath, Maybe FilePath) -> [(String, Renderer a String, Both FilePath, Maybe FilePath)]
testsForPaths (paths, json, patch, split) = [ ("json", testJSON, paths, json), ("patch", P.patch, paths, patch), ("split", testSplit, paths, split) ]
2016-02-18 00:06:24 +03:00
testSplit :: Renderer a String
testSplit diff sources = TL.unpack $ Split.split diff sources
testJSON :: Renderer a String
2016-03-01 04:52:30 +03:00
testJSON diff sources = B.unpack $ J.json diff sources
2016-02-17 23:54:37 +03:00
2016-02-17 00:38:31 +03:00
-- | Return all the examples from the given directory. Examples are expected to
2016-02-27 03:04:47 +03:00
-- | have the form "foo.A.js", "foo.B.js", "foo.patch.js". Diffs are not
2016-02-17 00:38:31 +03:00
-- | required as the test may be verifying that the inputs don't crash.
examples :: FilePath -> IO [(Both FilePath, Maybe FilePath, Maybe FilePath, Maybe FilePath)]
2016-02-17 00:38:31 +03:00
examples directory = do
2016-02-17 23:59:16 +03:00
as <- toDict <$> globFor "*.A.*"
bs <- toDict <$> globFor "*.B.*"
2016-02-26 00:19:33 +03:00
jsons <- toDict <$> globFor "*.json.*"
2016-02-18 00:10:28 +03:00
patches <- toDict <$> globFor "*.patch.*"
splits <- toDict <$> globFor "*.split.*"
2016-02-17 23:59:16 +03:00
let keys = Set.unions $ keysSet <$> [as, bs]
return $ (\name -> (Both (as ! name, bs ! name), Map.lookup name jsons, Map.lookup name patches, Map.lookup name splits)) <$> sort (Set.toList keys)
2016-02-17 00:38:31 +03:00
where
globFor :: String -> IO [FilePath]
globFor p = globDir1 (compile p) directory
2016-02-27 05:28:49 +03:00
toDict list = Map.fromList ((normalizeName <$> list) `Prelude.zip` list)
2016-02-17 00:38:31 +03:00
-- | Given a test name like "foo.A.js", return "foo.js".
normalizeName :: FilePath -> FilePath
normalizeName path = addExtension (dropExtension $ dropExtension path) (takeExtension path)
-- | Given file paths for A, B, and, optionally, a diff, return whether diffing
-- | the files will produce the diff. If no diff is provided, then the result
-- | is true, but the diff will still be calculated.
2016-02-29 06:18:44 +03:00
testDiff :: Renderer T.Text String -> Both FilePath -> Maybe FilePath -> (String -> String -> Expectation) -> Expectation
testDiff renderer paths diff matcher = do
2016-03-01 03:39:04 +03:00
let parser = parserForFilepath (fst paths)
2016-02-29 05:08:07 +03:00
sources <- sequence $ readAndTranscodeFile <$> paths
2016-03-09 00:20:17 +03:00
let sourceBlobs = Both (S.SourceBlob, S.SourceBlob) <*> sources <*> pure mempty <*> paths <*> pure (Just S.defaultPlainBlob)
2016-02-23 00:04:39 +03:00
actual <- diffFiles parser renderer sourceBlobs
2016-02-17 00:38:31 +03:00
case diff of
Nothing -> matcher actual actual
2016-02-17 00:38:31 +03:00
Just file -> do
2016-02-17 23:54:37 +03:00
expected <- readFile file
2016-02-29 06:18:44 +03:00
matcher actual expected