2016-02-16 20:33:41 +03:00
|
|
|
module CorpusSpec where
|
|
|
|
|
2016-02-17 00:38:31 +03:00
|
|
|
import Diffing
|
2016-02-18 01:10:04 +03:00
|
|
|
import PatchOutput
|
2016-02-17 23:54:37 +03:00
|
|
|
import Renderer
|
2016-02-18 00:06:24 +03:00
|
|
|
import Split
|
2016-02-17 00:38:31 +03:00
|
|
|
import Unified
|
|
|
|
|
|
|
|
import Data.Bifunctor.Join
|
|
|
|
import qualified Data.ByteString.Char8 as B1
|
|
|
|
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-02-17 00:38:31 +03:00
|
|
|
import Rainbow
|
|
|
|
import System.FilePath
|
|
|
|
import System.FilePath.Glob
|
2016-02-16 20:33:41 +03:00
|
|
|
import Test.Hspec
|
|
|
|
|
|
|
|
spec :: Spec
|
|
|
|
spec = do
|
2016-02-17 00:38:31 +03:00
|
|
|
describe "crashers should not crash" $ runTestsIn "test/crashers/"
|
|
|
|
describe "should produce the correct diff" $ runTestsIn "test/diffs/"
|
|
|
|
|
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
|
|
|
|
runTestsIn directory = do
|
2016-02-18 01:10:04 +03:00
|
|
|
paths <- runIO $ examples directory
|
|
|
|
let tests = correctTests =<< paths
|
2016-02-18 01:14:42 +03:00
|
|
|
mapM_ (\ (formatName, renderer, a, b, output) -> it (normalizeName a ++ " (" ++ formatName ++ ")") $ testDiff renderer a b output `shouldReturn` True) tests
|
2016-02-18 01:10:04 +03:00
|
|
|
|
2016-02-18 01:14:42 +03:00
|
|
|
correctTests :: (FilePath, FilePath, Maybe FilePath, Maybe FilePath, Maybe FilePath) -> [(String, Renderer a String, FilePath, FilePath, Maybe FilePath)]
|
2016-02-18 01:10:04 +03:00
|
|
|
correctTests paths@(_, _, Nothing, Nothing, Nothing) = testsForPaths paths
|
2016-02-18 01:14:42 +03:00
|
|
|
correctTests paths = List.filter (\(_, _, _, _, output) -> isJust output) $ testsForPaths paths
|
|
|
|
testsForPaths :: (FilePath, FilePath, Maybe FilePath, Maybe FilePath, Maybe FilePath) -> [(String, Renderer a String, FilePath, FilePath, Maybe FilePath)]
|
|
|
|
testsForPaths (a, b, patch, split, unified) = [ ("patch", PatchOutput.patch, a, b, patch), ("split", testSplit, a, b, split), ("unified", testUnified, a, b, unified) ]
|
2016-02-18 00:06:24 +03:00
|
|
|
testSplit :: Renderer a String
|
|
|
|
testSplit diff sources = TL.unpack $ Split.split diff sources
|
2016-02-17 23:54:37 +03:00
|
|
|
testUnified :: Renderer a String
|
|
|
|
testUnified diff sources = B1.unpack $ mconcat $ chunksToByteStrings toByteStringsColors0 $ unified diff sources
|
|
|
|
|
2016-02-17 00:38:31 +03:00
|
|
|
|
|
|
|
-- | Return all the examples from the given directory. Examples are expected to
|
2016-02-18 00:10:28 +03:00
|
|
|
-- | have the form "foo.A.js", "foo.B.js", "foo.unified.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.
|
2016-02-18 00:10:28 +03:00
|
|
|
examples :: FilePath -> IO [(FilePath, 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-18 00:10:28 +03:00
|
|
|
patches <- toDict <$> globFor "*.patch.*"
|
|
|
|
splits <- toDict <$> globFor "*.split.*"
|
2016-02-18 00:00:06 +03:00
|
|
|
unifieds <- toDict <$> globFor "*.unified.*"
|
2016-02-17 23:59:16 +03:00
|
|
|
let keys = Set.unions $ keysSet <$> [as, bs]
|
2016-02-18 00:10:28 +03:00
|
|
|
return $ (\name -> (as ! name, bs ! name, Map.lookup name patches, Map.lookup name splits, Map.lookup name unifieds)) <$> sort (Set.toList keys)
|
2016-02-17 00:38:31 +03:00
|
|
|
|
|
|
|
where
|
|
|
|
globFor :: String -> IO [FilePath]
|
|
|
|
globFor p = globDir1 (compile p) directory
|
|
|
|
toDict list = Map.fromList ((normalizeName <$> list) `zip` list)
|
|
|
|
|
|
|
|
-- | 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-17 23:54:37 +03:00
|
|
|
testDiff :: Renderer T.Text String -> FilePath -> FilePath -> Maybe FilePath -> IO Bool
|
|
|
|
testDiff renderer a b diff = do
|
2016-02-17 23:21:37 +03:00
|
|
|
let parser = parserForFilepath a
|
2016-02-17 00:38:31 +03:00
|
|
|
sources <- sequence $ readAndTranscodeFile <$> Join (a, b)
|
2016-02-17 23:54:37 +03:00
|
|
|
actual <- diffFiles parser renderer (runJoin sources)
|
2016-02-17 00:38:31 +03:00
|
|
|
case diff of
|
|
|
|
Nothing -> return $ actual /= "<should not be a thing>"
|
|
|
|
Just file -> do
|
2016-02-17 23:54:37 +03:00
|
|
|
expected <- readFile file
|
2016-02-17 00:38:31 +03:00
|
|
|
return $ expected == actual
|