Test to catch a bug in builtins.match

Also added infrastructure for comparing against current nix behavior,
not just current nix tests.
This commit is contained in:
Doug Beardsley 2018-04-06 16:20:21 -06:00 committed by John Wiegley
parent 96100172a0
commit 1b7dac071d
6 changed files with 188 additions and 205 deletions

View File

@ -1,32 +1,7 @@
let
hostPkgs = import <nixpkgs> {};
pinnedPkgs = hostPkgs.fetchFromGitHub {
owner = "NixOS";
repo = "nixpkgs-channels";
rev = "ee28e35ba37ab285fc29e4a09f26235ffe4123e2";
sha256 = "0a6xrqjj2ihkz1bizhy5r843n38xgimzw5s2mfc42kk2rgc95gw5";
};
in { nixpkgs ? import pinnedPkgs {}
, compiler ? "ghc822"
, doProfiling ? false
, doBenchmark ? false }:
let
inherit (nixpkgs) pkgs;
haskellPackages = let hpkgs = pkgs.haskell.packages.${compiler}; in
hpkgs // {
mkDerivation = args: hpkgs.mkDerivation (args // {
enableLibraryProfiling = doProfiling;
enableExecutableProfiling = doProfiling;
});
};
pkg = haskellPackages.developPackage {
{ pkgs ? import <nixpkgs> {} }: pkgs.haskellPackages.developPackage {
root = ./.;
source-overrides = {
unordered-containers = "0.2.9.0";
# Use a particular commit from github
insert-ordered-containers = pkgs.fetchFromGitHub {
owner = "mightybyte";
@ -35,10 +10,4 @@ let
sha256 = "0l0g6ns5bcrcaij0wbdgc04qyl9h0vk1kx9lkzdkwj9v51l26azm";
};
};
};
variant = if doBenchmark
then pkgs.haskell.lib.doBenchmark
else pkgs.lib.id;
in variant pkg
}

View File

@ -1,189 +1,155 @@
-- This file has been generated from package.yaml by hpack version 0.27.0.
--
-- see: https://github.com/sol/hpack
--
-- hash: 429fc2370bb078161c283b1238eb797ca1c03c46e4c1a2f68ac80937a901bb79
Name: hnix
Version: 0.5.0
Synopsis: Haskell implementation of the Nix language
Description:
Haskell implementation of the Nix language.
name: hnix
version: 0.5.0
synopsis: Haskell implementation of the Nix language
description: Haskell implementation of the Nix language.
category: System, Data, Nix
homepage: https://github.com/jwiegley/hnix#readme
bug-reports: https://github.com/jwiegley/hnix/issues
author: John Wiegley
maintainer: johnw@newartisans.com
license: BSD3
license-file: LICENSE
build-type: Simple
cabal-version: >= 1.10
License: BSD3
License-file: LICENSE
Author: John Wiegley
Maintainer: johnw@newartisans.com
Category: Data, Nix
Build-type: Simple
Cabal-version: >=1.10
Homepage: http://github.com/jwiegley/hnix
extra-source-files:
README.md
Extra-source-files: data/*.nix
source-repository head
type: git
location: https://github.com/jwiegley/hnix
Flag Parsec
Description: Use parsec instead of Trifecta
Default: False
flag parsec
description: Use parsec instead of Trifecta
manual: True
default: False
library
exposed-modules:
Nix
Nix.Atoms
Nix.Builtins
Nix.Eval
Nix.Expr
Nix.Expr.Shorthands
Nix.Expr.Types
Nix.Expr.Types.Annotated
Nix.Lint
Nix.Monad
Nix.Monad.Instance
Nix.Parser
Nix.Parser.Library
Nix.Parser.Operators
Nix.Pretty
Nix.Scope
Nix.Stack
Nix.StringOperations
Nix.TH
Nix.Thunk
Nix.Utils
Nix.Value
Nix.XML
other-modules:
Paths_hnix
hs-source-dirs:
src
ghc-options: -Wall
build-depends:
aeson
Library
Default-language: Haskell2010
Exposed-modules:
Nix
Nix.Atoms
Nix.Scope
Nix.Stack
Nix.Eval
Nix.XML
Nix.Thunk
Nix.Lint
Nix.Monad
Nix.Monad.Instance
Nix.Builtins
Nix.Parser
Nix.Expr
Nix.Pretty
Nix.Parser.Operators
Nix.StringOperations
Nix.TH
Nix.Expr.Types
Nix.Expr.Types.Annotated
Other-modules:
Nix.Parser.Library
Nix.Expr.Shorthands
Nix.Utils
Build-depends:
base >= 4.9 && < 5
, aeson
, ansi-wl-pprint
, array >=0.4 && <0.6
, base >=4.9 && <5
, array >= 0.4 && < 0.6
, base16-bytestring
, bytestring
, containers
, cryptohash
, data-fix
, deepseq
, deriving-compat >=0.3 && <0.5
, directory
, exceptions
, filepath
, insert-ordered-containers >=0.2.2 && <0.3
, deriving-compat >= 0.3 && < 0.5
, text
, bytestring
, monadlist
, mtl
, parsers >=0.10
, transformers
, parsers >= 0.10
, insert-ordered-containers >= 0.2.2
, unordered-containers >= 0.2.9 && < 0.3
, data-fix
, deepseq
, exceptions
, insert-ordered-containers >= 0.2.2 && < 0.3
, process
, directory
, filepath
, scientific
, semigroups >= 0.18 && < 0.19
, split
, template-haskell
, regex-tdfa
, regex-tdfa-text
, scientific
, semigroups >=0.18 && <0.19
, split
, syb
, template-haskell
, text
, these
, transformers
, unix
, unordered-containers >=0.2.9 && <0.3
, syb
, vector
, xml
if flag(parsec)
cpp-options: -DUSE_PARSEC
build-depends:
parsec
Cpp-options: -DUSE_PARSEC
Build-depends: parsec
else
build-depends:
trifecta
default-language: Haskell2010
executable hnix
main-is: Main.hs
other-modules:
Paths_hnix
hs-source-dirs:
main
Build-depends: trifecta
ghc-options: -Wall
build-depends:
ansi-wl-pprint
, base >=4.9 && <5
Executable hnix
Default-language: Haskell2010
Main-is: Main.hs
Hs-source-dirs: main
Build-depends:
base >= 4.3 && < 5
, hnix
, containers
, ansi-wl-pprint
, data-fix
, deepseq
, exceptions
, hnix
, insert-ordered-containers >=0.2.2 && <0.3
, mtl
, optparse-applicative
, template-haskell
, text
, template-haskell
, transformers
, unordered-containers >=0.2.9 && <0.3
default-language: Haskell2010
test-suite hnix-tests
type: exitcode-stdio-1.0
main-is: Main.hs
other-modules:
EvalTests
NixLanguageTests
ParserTests
PrettyTests
Paths_hnix
hs-source-dirs:
tests
ghc-options: -Wall
build-depends:
Glob
, ansi-wl-pprint
, base >=4.9 && <5
, containers
, data-fix
, exceptions
, filepath
Ghc-options: -Wall
Test-suite hnix-tests
Type: exitcode-stdio-1.0
Hs-source-dirs: tests
Default-language: Haskell2010
Main-is: Main.hs
Other-modules:
TestCommon
ParserTests
EvalTests
PrettyTests
NixLanguageTests
Build-depends:
base >= 4.3 && < 5
, containers
, text
, data-fix
, hnix
, insert-ordered-containers >=0.2.2 && <0.3
, interpolate
, mtl
, tasty
, tasty-th
, tasty-hunit
, directory
, Glob
, filepath
, process
, split
, tasty
, tasty-hunit
, tasty-th
, template-haskell
, text
, transformers
, interpolate
, insert-ordered-containers
, unix
, unordered-containers >=0.2.9 && <0.3
default-language: Haskell2010
, unordered-containers
benchmark hnix-benchmarks
type: exitcode-stdio-1.0
main-is: Main.hs
other-modules:
ParserBench
Paths_hnix
hs-source-dirs:
benchmarks
ghc-options: -Wall
build-depends:
ansi-wl-pprint
, base >=4.9 && <5
Benchmark hnix-benchmarks
Type: exitcode-stdio-1.0
Hs-source-dirs: benchmarks
Default-language: Haskell2010
Main-is: Main.hs
Other-modules:
ParserBench
Build-depends:
base >= 4.3 && < 5
, containers
, criterion
, data-fix
, exceptions
, hnix
, insert-ordered-containers >=0.2.2 && <0.3
, mtl
, template-haskell
, text
, transformers
, unordered-containers >=0.2.9 && <0.3
default-language: Haskell2010
, hnix
, criterion
source-repository head
type: git
location: git://github.com/jwiegley/hnix.git

View File

@ -399,13 +399,13 @@ match_ pat str = force pat $ \pat' -> force str $ \str' ->
case (pat', str') of
-- jww (2018-04-05): We should create a fundamental type for compiled
-- regular expressions if it turns out they get used often.
(NVStr p _, NVStr s _) -> return $ NVList $
(NVStr p _, NVStr s _) -> return $
let re = makeRegex (encodeUtf8 p) :: Regex
in case matchOnceText re (encodeUtf8 s) of
Just ("", sarr, "") -> let s = map fst (elems sarr) in
map (valueThunk @m . flip NVStr mempty . decodeUtf8)
NVList $ map (valueThunk @m . flip NVStr mempty . decodeUtf8)
(if length s > 1 then tail s else s)
_ -> []
_ -> NVConstant NNull
(p, s) ->
throwError $ "builtins.match: expected a regex"
++ " and a string, but got: " ++ show (p, s)

View File

@ -14,6 +14,7 @@ import Nix.Value
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.TH
import TestCommon
case_basic_sum =
constantEqualStr "2" "1 + 1"
@ -71,6 +72,8 @@ case_function_recursive_sets =
case_nested_with =
constantEqualStr "2" "with { x = 1; }; with { x = 2; }; x"
case_match_failure_null = assertEvalMatchesNix "builtins.match \"ab\" \"abc\""
-----------------------
tests :: TestTree

View File

@ -2,7 +2,7 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module NixLanguageTests (genTests) where
module NixLanguageTests where --(genTests) where
import Control.Arrow ((&&&))
import Control.Exception
@ -23,11 +23,17 @@ import Nix.Utils
import Nix.Stack
import Nix.Value
import Nix.XML
import System.Directory
import System.Environment
import System.FilePath
import System.FilePath.Glob (compile, globDir1)
import System.IO
import System.Posix.Temp
import System.Process
import Test.Tasty
import Test.Tasty.HUnit
import Text.Printf
import TestCommon
{-
From (git://nix)/tests/lang.sh we see that
@ -49,7 +55,6 @@ From (git://nix)/tests/lang.sh we see that
TEST_VAR=foo should be in all the environments # for eval-okay-getenv.nix
-}
groupBy :: Ord k => (v -> k) -> [v] -> Map k [v]
groupBy key = Map.fromListWith (++) . map (key &&& pure)
@ -94,13 +99,13 @@ assertParseFail file = do
assertLangOk :: FilePath -> Assertion
assertLangOk file = do
actual <- printNix <$> nixEvalFile (file ++ ".nix")
actual <- printNix <$> hnixEvalFile (file ++ ".nix")
expected <- Text.readFile $ file ++ ".exp"
assertEqual "" expected $ Text.pack (actual ++ "\n")
assertLangOkXml :: FilePath -> Assertion
assertLangOkXml file = do
actual <- toXML <$> nixEvalFile (file ++ ".nix")
actual <- toXML <$> hnixEvalFile (file ++ ".nix")
expected <- Text.readFile $ file ++ ".exp.xml"
assertEqual "" expected $ Text.pack actual
@ -127,13 +132,3 @@ assertEvalFail file = catch ?? (\(_ :: SomeException) -> return ()) $ do
evalResult `seq` assertFailure $
file ++ " should not evaluate.\nThe evaluation result was `"
++ evalResult ++ "`."
nixEvalFile :: FilePath -> IO (NValueNF (Lazy IO))
nixEvalFile file = do
parseResult <- parseNixFileLoc file
case parseResult of
Failure err ->
error $ "Parsing failed for file `" ++ file ++ "`.\n" ++ show err
Success expression -> do
setEnv "TEST_VAR" "foo"
evalLoc (Just file) expression

50
tests/TestCommon.hs Normal file
View File

@ -0,0 +1,50 @@
module TestCommon where
import Nix
import Nix.Monad
import Nix.Monad.Instance
import Nix.Parser
import Nix.Pretty
import System.Directory
import System.Environment
import System.IO
import System.Posix.Temp
import System.Process
import Test.Tasty.HUnit
hnixEvalFile :: FilePath -> IO (NValueNF (Lazy IO))
hnixEvalFile file = do
parseResult <- parseNixFileLoc file
case parseResult of
Failure err ->
error $ "Parsing failed for file `" ++ file ++ "`.\n" ++ show err
Success expression -> do
setEnv "TEST_VAR" "foo"
evalLoc (Just file) expression
hnixEvalString :: String -> IO (NValueNF (Lazy IO))
hnixEvalString expr = do
case parseNixString expr of
Failure err ->
error $ "Parsing failed for expressien `" ++ expr ++ "`.\n" ++ show err
Success expression -> eval Nothing expression
nixEvalString :: String -> IO String
nixEvalString expr = do
(fp,h) <- mkstemp "nix-test-eval"
hPutStr h expr
hClose h
res <- nixEvalFile fp
removeFile fp
return res
nixEvalFile :: FilePath -> IO String
nixEvalFile fp = do
readProcess "nix-instantiate" ["--eval", fp] ""
assertEvalMatchesNix :: String -> Assertion
assertEvalMatchesNix expr = do
hnixVal <- (++"\n") . printNix <$> hnixEvalString expr
nixVal <- nixEvalString expr
assertEqual expr nixVal hnixVal