on e94de40 help sign in
haskell.nix/test/default.nix
223 lines 9.0 kB history raw
1{ haskellNix ? import ../default.nix { inherit checkMaterialization; }
2, pkgs ? import nixpkgs nixpkgsArgs
3, nixpkgs ? haskellNix.sources.nixpkgs
4, nixpkgsArgs ? haskellNix.nixpkgsArgs
5, ifdLevel ? 1000
6, compiler-nix-name
7, checkMaterialization ? false
8}:
10with pkgs;
12let
13 # Set recurseForDerivations for both children and grand-children values in
14 # the input association list, but only if the key is "ifdInputs".
15 #
16 # withIfdInputs :: AttrSet -> AttrSet
17 #
18 # The values in the input attribute set must be attribute sets themselves.
19 #
20 # >>> withIfdInputs { ifdInputs = { plan-nix = { a = true; b = "hello"; }; }; cat = 2; }
21 # { ifdInputs = {
22 # plan-nix = {
23 # a = true;
24 # b = "hello";
25 # recurseForDerivations = true;
26 # };
27 # recurseForDerivations = true;
28 # };
29 # cat = 2;
30 # }
31 #
32 # >>> withIfdInputs { dog = "hello"; }
33 # { dog = "hello"; }
34 #
35 # >>> withIfdInputs { }
36 # { }
37 withIfdInputs =
38 builtins.mapAttrs
39 (name: val:
40 if name == "ifdInputs"
41 then
42 pkgs.recurseIntoAttrs
43 (builtins.mapAttrs (_: v: pkgs.haskell-nix.withInputs v) val)
44 else val
45 );
47 util = import ./util.nix { cabal-install = pkgs.evalPackages.haskell-nix.cabal-install.${compiler-nix-name}; };
49 # Map the values in an association list over the withIfdInputs function.
50 #
51 # addIfdInputsToVal :: AttrSet -> AttrSet
52 #
53 # The values in the input association list must be attribute sets themselves.
54 addIfdInputsToVal = builtins.mapAttrs (_: val: withIfdInputs val);
56 # Keep only the attribute with the key "ifdInputs".
57 #
58 # filterAttrsIfdInputs :: AttrSet -> AttrSet
59 #
60 # >>> filterAttrsIfdInputs { ifdInputs = 1; foobar = 2 }
61 # { ifdInputs = 1 }
62 #
63 # >>> filterAttrsIfdInputs { foobar = "hello" }
64 # { }
65 filterAttrsIfdInputs = pkgs.lib.filterAttrs (n: _: n == "ifdInputs");
67 # Remove all keys and values in a attribute set where the key
68 # doesn't equal "ifdInputs". Set the "recurseForDerivations"
69 # key in the resulting value.
70 #
71 # filterNonIfdInputsSetRecurse :: AttrSet -> AttrSet
72 #
73 # >>> filterNonIfdInputsSetRecurse { ifdInputs = 1; foobar = 2 }
74 # { ifdInputs = 1; recurseForDerivations = true }
75 #
76 # >>> filterNonIfdInputsSetRecurse { foobar = "hello" }
77 # { recurseForDerivations = true; }
78 filterNonIfdInputsSetRecurse = attrs:
79 pkgs.recurseIntoAttrs (filterAttrsIfdInputs attrs);
81 # Filter all out all the keys/values for child values of this attribute set
82 # where the key is not equal to "ifdInputs".
83 #
84 # filterNonIfdInputsValues :: AttrSet -> AttrSet
85 #
86 # The values in the input AttrSet must be attribute sets themselves.
87 #
88 # >>> filterNonIfdInputsValues { foo = { ifdInputs = 1; cat = 2; }; bar = { dog = "hello"; }; }
89 # { foo = {
90 # ifdInputs = 1;
91 # recurseForDerivations = true;
92 # };
93 # bar = {
94 # recurseForDerivations = true;
95 # };
96 # }
97 #
98 # >>> filterNonIfdInputsValues { }
99 # { }
100 filterNonIfdInputsValues = attrs:
101 builtins.mapAttrs (_: d: filterNonIfdInputsSetRecurse d) attrs;
103 # Call filterNonIfdInputsValues on the input attribute set, but only
104 # if ifdLevel is less than 3. Otherwise, just return the attribute set.
105 #
106 # filterNonIfdInputsValuesLTLevel3 :: AttrSet -> AttrSet
107 #
108 # >>> filterNonIfdInputsValuesLTLevel3 2 { cabal-doctests = { ifdInputs = {...}; run = ""; }; cabal-simple = { run = ""; }; }
109 # { cabal-doctests = {
110 # ifdInputs = {...};
111 # recurseForDerivations = true;
112 # };
113 # cabal-simple = {
114 # recurseForDerivations = true;
115 # };
116 # }
117 #
118 # >>> filterNonIfdInputsValuesLTLevel3 1000 { cabal-doctests = { ifdInputs = {...}; run = "..."; }; cabal-simple = { run = "..."; }; }
119 # { cabal-doctests = {
120 # ifdInputs = {...};
121 # run = "...";
122 # recurseForDerivations = true;
123 # };
124 # cabal-simple = {
125 # run = "...";
126 # recurseForDerivations = true;
127 # };
128 # }
129 #
130 # >>> filterNonIfdInputsValuesLTLevel3 0 { }
131 # { }
132 filterNonIfdInputsValuesLTLevel3 = ifdLevel: attrs:
133 if ifdLevel < 3
134 then filterNonIfdInputsValues attrs
135 else attrs;
137 testSrcRoot = haskell-nix.haskellLib.cleanGit { src = ../.; subDir = "test"; };
138 testSrc = subDir: haskell-nix.haskellLib.cleanSourceWith { src = testSrcRoot; inherit subDir; };
139 callTest = x: args: haskell-nix.callPackage x (args // { inherit testSrc; });
141 # Run unit tests with: nix-instantiate --eval --strict -A unit.tests
142 # An empty list means success.
143 unitTests =
144 let
145 tests = haskell-nix.callPackage ./unit.nix {};
146 testsFailedEcho = lib.concatMapStringsSep "\n" (t: "echo ${t.name} failed") tests;
147 testsFinalLine = if builtins.length tests == 0 then "\ntouch $out" else "\nexit 1";
148 testsScript = testsFailedEcho + testsFinalLine;
149 in
150 runCommand "unit-tests" { passthru = { inherit tests; }; } testsScript;
152 # All tests.
153 allTests = {
154 cabal-simple = callTest ./cabal-simple { inherit util compiler-nix-name; };
155 cabal-simple-prof = callTest ./cabal-simple-prof { inherit util compiler-nix-name; };
156 cabal-sublib = callTest ./cabal-sublib { inherit util compiler-nix-name; };
157 cabal-22 = callTest ./cabal-22 { inherit util compiler-nix-name; };
158 with-packages = callTest ./with-packages { inherit util; };
159 builder-haddock = callTest ./builder-haddock {};
160 stack-simple = callTest ./stack-simple {};
161 stack-local-resolver = callTest ./stack-local-resolver {};
162 stack-remote-resolver = callTest ./stack-remote-resolver {};
163 snapshots = callTest ./snapshots {};
164 shell-for = callTest ./shell-for {};
165 shell-for-setup-deps = callTest ./shell-for-setup-deps { inherit compiler-nix-name; };
166 setup-deps = import ./setup-deps { inherit pkgs compiler-nix-name; };
167 callStackToNix = callTest ./call-stack-to-nix {};
168 callCabalProjectToNix = callTest ./call-cabal-project-to-nix { inherit compiler-nix-name; };
169 cabal-source-repo = callTest ./cabal-source-repo { inherit compiler-nix-name; };
170 cabal-source-repo-comments = callTest ./cabal-source-repo-comments { inherit compiler-nix-name; };
171 buildable = callTest ./buildable { inherit compiler-nix-name; };
172 project-flags-cabal = callTest ./project-flags/cabal.nix { inherit compiler-nix-name; };
173 project-flags-stack = callTest ./project-flags/stack.nix {};
174 ghc-options-cabal = callTest ./ghc-options/cabal.nix { inherit compiler-nix-name; };
175 ghc-options-stack = callTest ./ghc-options/stack.nix {};
176 exe-only = callTest ./exe-only { inherit util compiler-nix-name; };
177 stack-source-repo = callTest ./stack-source-repo {};
178 extra-hackage = callTest ./extra-hackage { inherit compiler-nix-name; };
179 compiler-nix-name = callTest ./compiler-nix-name {};
180 hls-cabal = callTest ./haskell-language-server/cabal.nix { inherit compiler-nix-name; };
181 hls-stack = callTest ./haskell-language-server/stack.nix { inherit compiler-nix-name; };
182 cabal-hpack = callTest ./cabal-hpack { inherit util compiler-nix-name; };
183 index-state = callTest ./index-state { inherit compiler-nix-name; };
184 coverage = callTest ./coverage { inherit compiler-nix-name; };
186 unit = unitTests;
187 } // lib.optionalAttrs (!stdenv.hostPlatform.isGhcjs && compiler-nix-name != "ghc8101" && compiler-nix-name != "ghc8102" && compiler-nix-name != "ghc8102-experimental" ) {
188 # Pandoc does not build with ghcjs or ghc 8.10 yet (lookup-sha256 and fully-static build pandoc)
189 lookup-sha256 = callTest ./lookup-sha256 { inherit compiler-nix-name; };
190 fully-static = callTest ./fully-static { inherit (pkgs) buildPackages; };
191 } // lib.optionalAttrs (!pkgs.haskell-nix.haskellLib.isCrossHost) {
192 # Haddock is not included with cross compilers currently
193 sublib-docs = callTest ./sublib-docs { inherit util compiler-nix-name; };
194 };
196 # This is the same as allTests, but filter out all the key/vaules from the
197 # tests other than the "ifdInputs" key if the input ifdLevel is less than 3.
198 allTestsRemoveIfdLTLevel3 = ifdLevel:
199 filterNonIfdInputsValuesLTLevel3 ifdLevel allTests;
201 # This is the same as allTestsRemoveIfdLTLevel3, but make sure
202 # recurseForDerivations is set on all child values under the
203 # ifdInputs key.
204 allTestsWithIfdInputs = ifdLevel:
205 addIfdInputsToVal (allTestsRemoveIfdLTLevel3 ifdLevel);
207 # This is the same as allTestsWithIfdInputs, but returns an empty attribute set
208 # if the input ifdLevel is 0 or 1.
209 #
210 # Here is the result based on the input ifdLevel:
211 #
212 # - input ifdLevel is 0 or 1: {}
213 # - input ifdLevel is 2: filter out everything from the children of allTests
214 # except for the ifdInputs attribute
215 # - input ifdLevel is 3 or greater: return allTests
216 optionalIfdTests = ifdLevel:
217 pkgs.lib.optionalAttrs (ifdLevel > 1) (allTestsWithIfdInputs ifdLevel);
218in pkgs.recurseIntoAttrs (optionalIfdTests ifdLevel)
220## more possible test cases
221# 1. fully static linking
222# 2. cabal 2.4 stuff
223# 3. cross-compiling