mirror of
https://github.com/reanimate/reanimate.git
synced 2026-09-11 16:12:20 +00:00
setup unit tests for Nix
Both for a `nix-build`, where `cabal` executable is not present, but also just for using Stack with nix integration. With nix integration, Stack will make a `nix-shell` where `stack` executable is not found. We use "bare-bones" GHC to solve this. This GHC doesn't exactly respect our Stack or Cabal configurations, so we need to avoid `cubicbezier`'s `matrices` dependency so that `Data.Matrix` resolves to `matrix` package. Also, we don't error on compiler warnings when compiling test files through Nix. I don't know if these warnings would show up on a regular Stack or Cabal config (I'm on NixOS), so it's unaffected for those. TL;DR: Added testing support for Nix build environments; Cabal and Stack environments should be unchanged.
This commit is contained in:
parent
bae6456026
commit
a9b758ea0a
5 changed files with 137 additions and 16 deletions
|
|
@ -60,6 +60,10 @@ op2LaTeX LeftParen = "("
|
||||||
op2LaTeX RightParen = ")"
|
op2LaTeX RightParen = ")"
|
||||||
|
|
||||||
-- Some supportive types and instances.
|
-- Some supportive types and instances.
|
||||||
|
instance Functor (Expr a) where
|
||||||
|
fmap f (Var x) = Var (f x)
|
||||||
|
fmap f (BinOp x op y) = BinOp (fmap f x) op (fmap f y)
|
||||||
|
fmap f (Paren l x r) = Paren l (fmap f x) r
|
||||||
|
|
||||||
instance Bifunctor Expr where
|
instance Bifunctor Expr where
|
||||||
bimap _ g (Var x) = Var (g x)
|
bimap _ g (Var x) = Var (g x)
|
||||||
|
|
@ -91,6 +95,9 @@ instance Bitraversable p => Traversable (Both p) where
|
||||||
-- | Make a bifunctor @f (a, -) (b, -)@ (namely @BiAlongside a b f@) out of @f@.
|
-- | Make a bifunctor @f (a, -) (b, -)@ (namely @BiAlongside a b f@) out of @f@.
|
||||||
newtype BiAlongside a b f x y = BiAlongside { runBiAlongside :: f (a, x) (b, y) }
|
newtype BiAlongside a b f x y = BiAlongside { runBiAlongside :: f (a, x) (b, y) }
|
||||||
|
|
||||||
|
instance Bifunctor p => Functor (BiAlongside a b p c) where
|
||||||
|
fmap f (BiAlongside x) = BiAlongside (bimap id (fmap f) x)
|
||||||
|
|
||||||
instance Bifunctor p => Bifunctor (BiAlongside a b p) where
|
instance Bifunctor p => Bifunctor (BiAlongside a b p) where
|
||||||
bimap f g = BiAlongside . bimap (second f) (second g) . runBiAlongside
|
bimap f g = BiAlongside . bimap (second f) (second g) . runBiAlongside
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
module Main (main) where
|
module Main (main) where
|
||||||
|
|
||||||
import Codec.Picture
|
import Codec.Picture
|
||||||
|
import Control.Monad (forM_, when, zipWithM_)
|
||||||
import Control.Monad.ST
|
import Control.Monad.ST
|
||||||
import Control.Monad.State.Strict
|
import Control.Monad.State.Strict
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
resolver: lts-18.15
|
resolver: lts-24.25
|
||||||
|
|
||||||
allow-newer: false
|
allow-newer: false
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
- .
|
- .
|
||||||
|
|
||||||
extra-deps: []
|
extra-deps:
|
||||||
|
- geojson-4.1.1@sha256:f450e81d4fe1993f97c7cdb2b9743d54d2621c37b67d8a89536e5e09d33fd737,4233
|
||||||
|
- reanimate-svg-0.13.0.1@sha256:260957e61e2e290a6cbca1d129fa0da66d624a224d0016d3bdc76fa210c70cbd,2950
|
||||||
|
|
||||||
|
|
|
||||||
26
stack.yaml.lock
Normal file
26
stack.yaml.lock
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# This file was autogenerated by Stack.
|
||||||
|
# You should not edit this file by hand.
|
||||||
|
# For more information, please see the documentation at:
|
||||||
|
# https://docs.haskellstack.org/en/stable/topics/lock_files
|
||||||
|
|
||||||
|
packages:
|
||||||
|
- completed:
|
||||||
|
hackage: geojson-4.1.1@sha256:f450e81d4fe1993f97c7cdb2b9743d54d2621c37b67d8a89536e5e09d33fd737,4233
|
||||||
|
pantry-tree:
|
||||||
|
sha256: 0a1c1e2c6533b27efd472de9931e99d5cd05e0db568840e6e6dc014c8a2591cd
|
||||||
|
size: 2376
|
||||||
|
original:
|
||||||
|
hackage: geojson-4.1.1@sha256:f450e81d4fe1993f97c7cdb2b9743d54d2621c37b67d8a89536e5e09d33fd737,4233
|
||||||
|
- completed:
|
||||||
|
hackage: reanimate-svg-0.13.0.1@sha256:260957e61e2e290a6cbca1d129fa0da66d624a224d0016d3bdc76fa210c70cbd,2950
|
||||||
|
pantry-tree:
|
||||||
|
sha256: 93a217570c21431d5c9cf369058c8227aa1dee3a506edfed324550969c55a685
|
||||||
|
size: 39432
|
||||||
|
original:
|
||||||
|
hackage: reanimate-svg-0.13.0.1@sha256:260957e61e2e290a6cbca1d129fa0da66d624a224d0016d3bdc76fa210c70cbd,2950
|
||||||
|
snapshots:
|
||||||
|
- completed:
|
||||||
|
sha256: c0060a2ed91942bd6426f00617125fe9f0fef613dad0acc5f0ea10e8d499f799
|
||||||
|
size: 726335
|
||||||
|
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/24/25.yaml
|
||||||
|
original: lts-24.25
|
||||||
|
|
@ -5,9 +5,11 @@ module UnitTests
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Exception
|
import Control.Exception
|
||||||
|
import Control.Monad (filterM)
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Lazy as LBS
|
import qualified Data.ByteString.Lazy as LBS
|
||||||
import Data.List (sort)
|
import Data.List (sort)
|
||||||
|
import Data.Maybe (maybe)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.IO as T
|
import qualified Data.Text.IO as T
|
||||||
import System.Directory
|
import System.Directory
|
||||||
|
|
@ -23,22 +25,78 @@ import Test.Tasty.HUnit
|
||||||
data BuildSystem
|
data BuildSystem
|
||||||
= Cabal
|
= Cabal
|
||||||
| Stack
|
| Stack
|
||||||
|
| NixBuild NixBuildSystem
|
||||||
|
|
||||||
|
data NixBuildSystem
|
||||||
|
= NixCabal
|
||||||
|
| NixStack
|
||||||
|
|
||||||
|
-- required for nix build
|
||||||
|
nixGHCOptions :: [String]
|
||||||
|
nixGHCOptions =
|
||||||
|
[ "-XPackageImports"
|
||||||
|
, "-XPatternSynonyms"
|
||||||
|
, "-Wall"
|
||||||
|
, "-fno-ignore-asserts"
|
||||||
|
, "-DNO_HGEOMETRY"
|
||||||
|
, "-hide-package"
|
||||||
|
, "matrices"
|
||||||
|
]
|
||||||
|
|
||||||
|
findStackAutogen :: IO (Maybe FilePath)
|
||||||
|
findStackAutogen = do
|
||||||
|
let base = ".stack-work" </> "dist"
|
||||||
|
baseExists <- doesDirectoryExist base
|
||||||
|
if not baseExists
|
||||||
|
then return Nothing
|
||||||
|
else do
|
||||||
|
subDirs <- listDirectories base
|
||||||
|
case subDirs of
|
||||||
|
[] -> return Nothing
|
||||||
|
(arch:_) -> do
|
||||||
|
let archPath = base </> arch
|
||||||
|
cabalDirs <- listDirectories archPath
|
||||||
|
case cabalDirs of
|
||||||
|
[] -> return Nothing
|
||||||
|
(ver:_) -> return $ Just (archPath </> ver </> "build" </> "autogen")
|
||||||
|
|
||||||
|
includeBuild :: NixBuildSystem -> IO [String]
|
||||||
|
includeBuild NixCabal = return ["-idist/build/autogen"]
|
||||||
|
includeBuild NixStack = do
|
||||||
|
mbPath <- findStackAutogen
|
||||||
|
case mbPath of
|
||||||
|
Nothing -> return []
|
||||||
|
Just p -> return ["-i" ++ p]
|
||||||
|
|
||||||
|
listDirectories :: FilePath -> IO [FilePath]
|
||||||
|
listDirectories path = do
|
||||||
|
contents <- listDirectory path
|
||||||
|
filterM (\f -> doesDirectoryExist (path </> f)) contents
|
||||||
|
|
||||||
{-# NOINLINE buildSystem #-}
|
{-# NOINLINE buildSystem #-}
|
||||||
buildSystem :: BuildSystem
|
buildSystem :: BuildSystem
|
||||||
buildSystem = unsafePerformIO $ do
|
buildSystem = unsafePerformIO $ do
|
||||||
|
exeCabal <- findExecutable "cabal"
|
||||||
|
exeStack <- findExecutable "stack"
|
||||||
|
|
||||||
newbuild <- doesDirectoryExist "dist-newstyle"
|
newbuild <- doesDirectoryExist "dist-newstyle"
|
||||||
stack <- doesDirectoryExist ".stack-work"
|
v1build <- doesDirectoryExist "dist"
|
||||||
if newbuild then pure Cabal
|
stack <- doesDirectoryExist ".stack-work"
|
||||||
else if stack then pure Stack
|
|
||||||
else error "Unknown build system."
|
return $ case (exeCabal, exeStack) of
|
||||||
|
(Nothing, _) | v1build -> NixBuild NixCabal
|
||||||
|
(_, Nothing) | stack -> NixBuild NixStack
|
||||||
|
(Just _, _) | newbuild -> Cabal
|
||||||
|
(_, Just _) | stack -> Stack
|
||||||
|
_ -> error "Unknown build system."
|
||||||
|
|
||||||
{-# NOINLINE unitTestsDisabled #-}
|
{-# NOINLINE unitTestsDisabled #-}
|
||||||
unitTestsDisabled :: Bool
|
unitTestsDisabled :: Bool
|
||||||
unitTestsDisabled =
|
unitTestsDisabled =
|
||||||
case buildSystem of
|
case buildSystem of
|
||||||
Cabal -> False
|
Cabal -> False
|
||||||
Stack -> unsafePerformIO $ do
|
NixBuild _ -> False
|
||||||
|
Stack -> unsafePerformIO $ do
|
||||||
(ret, _, _) <- readProcessWithExitCode "stack" ["exec","--","ghc", "-e", "Reanimate.duration Reanimate.Builtin.Documentation.drawCircle"] ""
|
(ret, _, _) <- readProcessWithExitCode "stack" ["exec","--","ghc", "-e", "Reanimate.duration Reanimate.Builtin.Documentation.drawCircle"] ""
|
||||||
case ret of
|
case ret of
|
||||||
ExitFailure{} -> pure True
|
ExitFailure{} -> pure True
|
||||||
|
|
@ -64,16 +122,26 @@ unitTestFolder path = do
|
||||||
genGolden :: FilePath -> IO LBS.ByteString
|
genGolden :: FilePath -> IO LBS.ByteString
|
||||||
genGolden path = do
|
genGolden path = do
|
||||||
(inh, outh, errh, pid) <- case buildSystem of
|
(inh, outh, errh, pid) <- case buildSystem of
|
||||||
Stack -> runInteractiveProcess "stack" ["runhaskell", path, "test"]
|
Stack -> runInteractiveProcess "stack" ["runhaskell", path, "test"]
|
||||||
Nothing Nothing
|
Nothing Nothing
|
||||||
Cabal -> runInteractiveProcess "cabal" ["v2-exec", "runhaskell", path, "test"]
|
Cabal -> runInteractiveProcess "cabal" ["v2-exec", "runhaskell", path, "test"]
|
||||||
Nothing Nothing
|
Nothing Nothing
|
||||||
|
NixBuild nixbuild -> do
|
||||||
|
nixIncludeDir <- includeBuild nixbuild
|
||||||
|
runInteractiveProcess "ghc"
|
||||||
|
( ["-isrc", "-iunix"]
|
||||||
|
++ nixIncludeDir
|
||||||
|
++ nixGHCOptions
|
||||||
|
++ ["--run", path, "--", "test"]
|
||||||
|
) Nothing Nothing
|
||||||
-- hSetBinaryMode outh True
|
-- hSetBinaryMode outh True
|
||||||
-- hSetNewlineMode outh universalNewlineMode
|
-- hSetNewlineMode outh universalNewlineMode
|
||||||
|
|
||||||
hClose inh
|
hClose inh
|
||||||
out <- BS.hGetContents outh
|
out <- BS.hGetContents outh
|
||||||
err <- T.hGetContents errh
|
err <- T.hGetContents errh
|
||||||
code <- waitForProcess pid
|
code <- waitForProcess pid
|
||||||
|
|
||||||
case code of
|
case code of
|
||||||
ExitSuccess -> return $ LBS.fromChunks [out]
|
ExitSuccess -> return $ LBS.fromChunks [out]
|
||||||
ExitFailure{} -> error $ "Failed to run: " ++ T.unpack err
|
ExitFailure{} -> error $ "Failed to run: " ++ T.unpack err
|
||||||
|
|
@ -87,9 +155,17 @@ compileTestFolder path = do
|
||||||
[ testCase file $ do
|
[ testCase file $ do
|
||||||
(ret, _stdout, err) <-
|
(ret, _stdout, err) <-
|
||||||
case buildSystem of
|
case buildSystem of
|
||||||
Stack -> readProcessWithExitCode "stack" (["ghc","--", fullPath] ++ ghcOpts) ""
|
Stack -> readProcessWithExitCode "stack" (["ghc","--", fullPath] ++ ghcOpts) ""
|
||||||
Cabal -> readProcessWithExitCode "cabal"
|
Cabal -> readProcessWithExitCode "cabal"
|
||||||
(["v2-exec","ghc","--", "-package", "reanimate", fullPath] ++ ghcOpts) ""
|
(["v2-exec","ghc","--", "-package", "reanimate", fullPath] ++ ghcOpts) ""
|
||||||
|
NixBuild nixbuild -> do
|
||||||
|
nixIncludeDir <- includeBuild nixbuild
|
||||||
|
readProcessWithExitCode "ghc"
|
||||||
|
( ["-isrc", "-iunix"]
|
||||||
|
++ nixIncludeDir
|
||||||
|
++ nixGHCOptions
|
||||||
|
++ [fullPath] ++ (init ghcOpts)
|
||||||
|
) ""
|
||||||
_ <- evaluate (length err)
|
_ <- evaluate (length err)
|
||||||
case ret of
|
case ret of
|
||||||
ExitFailure{} -> assertFailure $ "Failed to compile:\n" ++ err
|
ExitFailure{} -> assertFailure $ "Failed to compile:\n" ++ err
|
||||||
|
|
@ -100,7 +176,7 @@ compileTestFolder path = do
|
||||||
, notElem (replaceExtension file "golden") goldenFiles
|
, notElem (replaceExtension file "golden") goldenFiles
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
ghcOpts = ["-fno-code", "-O0", "-Werror", "-Wall"]
|
ghcOpts = ["-fno-code", "-O0", "-Wall", "-Werror"]
|
||||||
|
|
||||||
compileVideoFolder :: FilePath -> IO TestTree
|
compileVideoFolder :: FilePath -> IO TestTree
|
||||||
compileVideoFolder _ | unitTestsDisabled = return $ testGroup "videos (disabled)" []
|
compileVideoFolder _ | unitTestsDisabled = return $ testGroup "videos (disabled)" []
|
||||||
|
|
@ -113,8 +189,16 @@ compileVideoFolder path = do
|
||||||
[ testCase dir $ do
|
[ testCase dir $ do
|
||||||
(ret, _stdout, err) <-
|
(ret, _stdout, err) <-
|
||||||
case buildSystem of
|
case buildSystem of
|
||||||
Stack -> readProcessWithExitCode "stack" (["ghc","--", "-i"++path</>dir, fullPath] ++ ghcOpts) ""
|
Stack -> readProcessWithExitCode "stack" (["ghc","--", "-i"++path</>dir, fullPath] ++ ghcOpts) ""
|
||||||
Cabal -> readProcessWithExitCode "cabal" (["v2-exec", "ghc","--", "-package", "reanimate", "-i"++path</>dir, fullPath] ++ ghcOpts) ""
|
Cabal -> readProcessWithExitCode "cabal" (["v2-exec", "ghc","--", "-package", "reanimate", "-i"++path</>dir, fullPath] ++ ghcOpts) ""
|
||||||
|
NixBuild nixbuild -> do
|
||||||
|
nixIncludeDir <- includeBuild nixbuild
|
||||||
|
readProcessWithExitCode "ghc"
|
||||||
|
( ["-isrc", "-iunix", "-i"++path</>dir]
|
||||||
|
++ nixIncludeDir
|
||||||
|
++ nixGHCOptions
|
||||||
|
++ [fullPath] ++ ghcOpts
|
||||||
|
) ""
|
||||||
_ <- evaluate (length err)
|
_ <- evaluate (length err)
|
||||||
case ret of
|
case ret of
|
||||||
ExitFailure{} -> assertFailure $ "Failed to compile:\n" ++ err
|
ExitFailure{} -> assertFailure $ "Failed to compile:\n" ++ err
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue