packages feed

hnix-0.13.0: tests/Main.hs

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE QuasiQuotes #-}

module Main where

import           Prelude hiding (lookupEnv)
import           Relude.Unsafe (read)
import qualified Control.Exception as Exc
import           GHC.Err (errorWithoutStackTrace)
import           Data.Fix
import           Data.List (isSuffixOf, lookup)
import qualified Data.String as String
import           Data.Time
import qualified EvalTests
import           NeatInterpolation (text)
import qualified Nix
import           Nix.Expr.Types
import           Nix.String
import           Nix.Options
import           Nix.Parser
import           Nix.Standard
import           Nix.Value
import qualified NixLanguageTests
import qualified ParserTests
import qualified PrettyTests
import qualified ReduceExprTests
import qualified PrettyParseTests
import           System.Directory
import           System.Environment (setEnv, lookupEnv)
import           System.FilePath.Glob
import           System.Posix.Files
import           Test.Tasty
import           Test.Tasty.HUnit

ensureLangTestsPresent :: Assertion
ensureLangTestsPresent = do
  exist <- fileExist "data/nix/tests/local.mk"
  unless exist $
    errorWithoutStackTrace $ String.unlines
      [ "Directory data/nix does not have any files."
      , "Did you forget to run"
          <> " \"git submodule update --init --recursive\"?" ]

ensureNixpkgsCanParse :: Assertion
ensureNixpkgsCanParse =
  consider "default.nix" (parseNixFile "default.nix") $ \case
    Fix (NAbs (ParamSet params _ _) _) -> do
      let rev    = getString "rev" params
          sha256 = getString "sha256" params
      consider "fetchTarball expression" (pure $ parseNixTextLoc [text|
        builtins.fetchTarball {
          url    = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
          sha256 = "${sha256}";
        }|]) $ \expr -> do
        NVStr ns <- do
          time <- getCurrentTime
          runWithBasicEffectsIO (defaultOptions time) $
            Nix.nixEvalExprLoc mempty expr
        let dir = stringIgnoreContext ns
        exists <- fileExist $ toString dir
        unless exists $
          errorWithoutStackTrace $
            "Directory " <> show dir <> " does not exist"
        files <- globDir1 (compile "**/*.nix") $ toString dir
        when (null files) $
          errorWithoutStackTrace $
            "Directory " <> show dir <> " does not have any files"
        for_ files $ \file -> do
          unless ("azure-cli/default.nix" `isSuffixOf` file ||
                  "os-specific/linux/udisks/2-default.nix"  `isSuffixOf` file) $ do
            -- Parse and deepseq the resulting expression tree, to ensure the
            -- parser is fully executed.
            _ <- consider file (parseNixFileLoc file) $ Exc.evaluate . force
            pass
    v -> fail $ "Unexpected parse from default.nix: " <> show v
 where
  getExpr   k m = let Just (Just r) = lookup k m in r
  getString k m =
      let Fix (NStr (DoubleQuoted [Plain str])) = getExpr k m in str

  consider path action k =
    do
      x <- action
      either
        (\ err -> errorWithoutStackTrace $ "Parsing " <> path <> " failed: " <> show err)
        k
        x

main :: IO ()
main = do
  nixLanguageTests    <- NixLanguageTests.genTests
  evalComparisonTests <- EvalTests.genEvalCompareTests
  let allOrLookup var = lookupEnv "ALL_TESTS" <|> lookupEnv var
  nixpkgsTestsEnv     <- allOrLookup "NIXPKGS_TESTS"
  prettyTestsEnv      <- lookupEnv "PRETTY_TESTS"

  pwd <- getCurrentDirectory
  setEnv "NIX_REMOTE" (pwd <> "/real-store")
  setEnv "NIX_DATA_DIR" (pwd <> "/data")

  defaultMain $ testGroup "hnix" $
    [ ParserTests.tests
    , EvalTests.tests
    , PrettyTests.tests
    , ReduceExprTests.tests] <>
    [ PrettyParseTests.tests
        (fromIntegral (read (fromMaybe "0" prettyTestsEnv) :: Int)) ] <>
    [ evalComparisonTests ] <>
    [ testCase "Nix language tests present" ensureLangTestsPresent
    , nixLanguageTests ] <>
    [ testCase "Nixpkgs parses without errors" ensureNixpkgsCanParse
      | isJust nixpkgsTestsEnv ]