at master 9.4 kB view raw
1{ 2 pkgs ? import ../.. { }, 3 currLibPath ? ../., 4 prevLibPath ? "${ 5 pkgs.fetchFromGitHub { 6 owner = "nixos"; 7 repo = "nixpkgs"; 8 # Parent commit of [#391544](https://github.com/NixOS/nixpkgs/pull/391544) 9 # Which was before the type.merge.v2 introduction 10 rev = "bcf94dd3f07189b7475d823c8d67d08b58289905"; 11 hash = "sha256-MuMiIY3MX5pFSOCvutmmRhV6RD0R3CG0Hmazkg8cMFI="; 12 } 13 }/lib", 14}: 15let 16 lib = import currLibPath; 17 18 lib_with_merge_v2 = lib; 19 lib_with_merge_v1 = import prevLibPath; 20 21 getMatrix = 22 { 23 getType ? null, 24 # If getType is set this is only used as test prefix 25 # And the type from getType is used 26 outerTypeName, 27 innerTypeName, 28 value, 29 testAttrs, 30 }: 31 let 32 evalModules.call_v1 = lib_with_merge_v1.evalModules; 33 evalModules.call_v2 = lib_with_merge_v2.evalModules; 34 outerTypes.outer_v1 = lib_with_merge_v1.types; 35 outerTypes.outer_v2 = lib_with_merge_v2.types; 36 innerTypes.inner_v1 = lib_with_merge_v1.types; 37 innerTypes.inner_v2 = lib_with_merge_v2.types; 38 in 39 lib.mapAttrs ( 40 _: evalModules: 41 lib.mapAttrs ( 42 _: outerTypes: 43 lib.mapAttrs (_: innerTypes: { 44 "test_${outerTypeName}_${innerTypeName}" = testAttrs // { 45 expr = 46 (evalModules { 47 modules = [ 48 (m: { 49 options.foo = m.lib.mkOption { 50 type = 51 if getType != null then 52 getType outerTypes innerTypes 53 else 54 outerTypes.${outerTypeName} innerTypes.${innerTypeName}; 55 default = value; 56 }; 57 }) 58 ]; 59 }).config.foo; 60 }; 61 }) innerTypes 62 ) outerTypes 63 ) evalModules; 64in 65{ 66 # AttrsOf string 67 attrsOf_str_ok = getMatrix { 68 outerTypeName = "attrsOf"; 69 innerTypeName = "str"; 70 value = { 71 bar = "test"; 72 }; 73 testAttrs = { 74 expected = { 75 bar = "test"; 76 }; 77 }; 78 }; 79 attrsOf_str_err_inner = getMatrix { 80 outerTypeName = "attrsOf"; 81 innerTypeName = "str"; 82 value = { 83 bar = 1; # not a string 84 }; 85 testAttrs = { 86 expectedError = { 87 type = "ThrownError"; 88 msg = "A definition for option `foo.bar' is not of type `string'.*"; 89 }; 90 }; 91 }; 92 attrsOf_str_err_outer = getMatrix { 93 outerTypeName = "attrsOf"; 94 innerTypeName = "str"; 95 value = [ "foo" ]; # not an attrset 96 testAttrs = { 97 expectedError = { 98 type = "ThrownError"; 99 msg = "A definition for option `foo' is not of type `attribute set of string'.*"; 100 }; 101 }; 102 }; 103 104 # listOf string 105 listOf_str_ok = getMatrix { 106 outerTypeName = "listOf"; 107 innerTypeName = "str"; 108 value = [ 109 "foo" 110 "bar" 111 ]; 112 testAttrs = { 113 expected = [ 114 "foo" 115 "bar" 116 ]; 117 }; 118 }; 119 listOf_str_err_inner = getMatrix { 120 outerTypeName = "listOf"; 121 innerTypeName = "str"; 122 value = [ 123 "foo" 124 1 125 ]; # not a string 126 testAttrs = { 127 expectedError = { 128 type = "ThrownError"; 129 msg = ''A definition for option `foo."\[definition 1-entry 2\]"' is not of type `string'.''; 130 }; 131 }; 132 }; 133 listOf_str_err_outer = getMatrix { 134 outerTypeName = "listOf"; 135 innerTypeName = "str"; 136 value = { 137 foo = 42; 138 }; # not a list 139 testAttrs = { 140 expectedError = { 141 type = "ThrownError"; 142 msg = "A definition for option `foo' is not of type `list of string'.*"; 143 }; 144 }; 145 }; 146 147 attrsOf_submodule_ok = getMatrix { 148 getType = 149 a: b: 150 a.attrsOf ( 151 b.submodule (m: { 152 options.nested = m.lib.mkOption { 153 type = m.lib.types.str; 154 }; 155 }) 156 ); 157 outerTypeName = "attrsOf"; 158 innerTypeName = "submodule"; 159 value = { 160 foo = { 161 nested = "test1"; 162 }; 163 bar = { 164 nested = "test2"; 165 }; 166 }; 167 testAttrs = { 168 expected = { 169 foo = { 170 nested = "test1"; 171 }; 172 bar = { 173 nested = "test2"; 174 }; 175 }; 176 }; 177 }; 178 attrsOf_submodule_err_inner = getMatrix { 179 outerTypeName = "attrsOf"; 180 innerTypeName = "submodule"; 181 getType = 182 a: b: 183 a.attrsOf ( 184 b.submodule (m: { 185 options.nested = m.lib.mkOption { 186 type = m.lib.types.str; 187 }; 188 }) 189 ); 190 value = { 191 foo = [ 1 ]; # not a submodule 192 bar = { 193 nested = "test2"; 194 }; 195 }; 196 testAttrs = { 197 expectedError = { 198 type = "ThrownError"; 199 msg = "A definition for option `foo.foo' is not of type `submodule'.*"; 200 }; 201 }; 202 }; 203 attrsOf_submodule_err_outer = getMatrix { 204 outerTypeName = "attrsOf"; 205 innerTypeName = "submodule"; 206 getType = 207 a: b: 208 a.attrsOf ( 209 b.submodule (m: { 210 options.nested = m.lib.mkOption { 211 type = m.lib.types.str; 212 }; 213 }) 214 ); 215 value = [ 123 ]; # not an attrsOf 216 testAttrs = { 217 expectedError = { 218 type = "ThrownError"; 219 msg = ''A definition for option `foo' is not of type `attribute set of \(submodule\).*''; 220 }; 221 }; 222 }; 223 224 # either 225 either_str_attrsOf_ok = getMatrix { 226 outerTypeName = "either"; 227 innerTypeName = "str_or_attrsOf_str"; 228 229 getType = a: b: a.either b.str (b.attrsOf a.str); 230 value = "string value"; 231 testAttrs = { 232 expected = "string value"; 233 }; 234 }; 235 either_str_attrsOf_err_1 = getMatrix { 236 outerTypeName = "either"; 237 innerTypeName = "str_or_attrsOf_str"; 238 239 getType = a: b: a.either b.str (b.attrsOf a.str); 240 value = 1; 241 testAttrs = { 242 expectedError = { 243 type = "ThrownError"; 244 msg = "A definition for option `foo' is not of type `string or attribute set of string'.*"; 245 }; 246 }; 247 }; 248 either_str_attrsOf_err_2 = getMatrix { 249 outerTypeName = "either"; 250 innerTypeName = "str_or_attrsOf_str"; 251 252 getType = a: b: a.either b.str (b.attrsOf a.str); 253 value = { 254 bar = 1; # not a string 255 }; 256 testAttrs = { 257 expectedError = { 258 type = "ThrownError"; 259 msg = "A definition for option `foo.bar' is not of type `string'.*"; 260 }; 261 }; 262 }; 263 264 # Coereced to 265 coerce_attrsOf_str_to_listOf_str_run = getMatrix { 266 outerTypeName = "coercedTo"; 267 innerTypeName = "attrsOf_str->listOf_str"; 268 getType = a: b: a.coercedTo (b.attrsOf b.str) builtins.attrValues (b.listOf b.str); 269 value = { 270 bar = "test1"; # coerced to listOf string 271 foo = "test2"; # coerced to listOf string 272 }; 273 testAttrs = { 274 expected = [ 275 "test1" 276 "test2" 277 ]; 278 }; 279 }; 280 coerce_attrsOf_str_to_listOf_str_final = getMatrix { 281 outerTypeName = "coercedTo"; 282 innerTypeName = "attrsOf_str->listOf_str"; 283 getType = a: b: a.coercedTo (b.attrsOf b.str) (abort "This shouldnt run") (b.listOf b.str); 284 value = [ 285 "test1" 286 "test2" 287 ]; # already a listOf string 288 testAttrs = { 289 expected = [ 290 "test1" 291 "test2" 292 ]; # Order should be kept 293 }; 294 }; 295 coerce_attrsOf_str_to_listOf_err_coercer_input = getMatrix { 296 outerTypeName = "coercedTo"; 297 innerTypeName = "attrsOf_str->listOf_str"; 298 getType = a: b: a.coercedTo (b.attrsOf b.str) builtins.attrValues (b.listOf b.str); 299 value = [ 300 { } 301 { } 302 ]; # not coercible to listOf string, with the given coercer 303 testAttrs = { 304 expectedError = { 305 type = "ThrownError"; 306 msg = ''A definition for option `foo."\[definition 1-entry 1\]"' is not of type `string'.*''; 307 }; 308 }; 309 }; 310 coerce_attrsOf_str_to_listOf_err_coercer_ouput = getMatrix { 311 outerTypeName = "coercedTo"; 312 innerTypeName = "attrsOf_str->listOf_str"; 313 getType = a: b: a.coercedTo (b.attrsOf b.str) builtins.attrValues (b.listOf b.str); 314 value = { 315 foo = { 316 bar = 1; 317 }; # coercer produces wrong type -> [ { bar = 1; } ] 318 }; 319 testAttrs = { 320 expectedError = { 321 type = "ThrownError"; 322 msg = ''A definition for option `foo."\[definition 1-entry 1\]"' is not of type `string'.*''; 323 }; 324 }; 325 }; 326 coerce_str_to_int_coercer_ouput = getMatrix { 327 outerTypeName = "coercedTo"; 328 innerTypeName = "int->str"; 329 getType = a: b: a.coercedTo b.int toString a.str; 330 value = [ ]; 331 testAttrs = { 332 expectedError = { 333 type = "ThrownError"; 334 msg = ''A definition for option `foo' is not of type `string or signed integer convertible to it.*''; 335 }; 336 }; 337 }; 338 339 # Submodule 340 submodule_with_ok = getMatrix { 341 outerTypeName = "submoduleWith"; 342 innerTypeName = "mixed_types"; 343 getType = 344 a: b: 345 a.submodule (m: { 346 options.attrs = m.lib.mkOption { 347 type = b.attrsOf b.str; 348 }; 349 options.list = m.lib.mkOption { 350 type = b.listOf b.str; 351 }; 352 options.either = m.lib.mkOption { 353 type = b.either a.str a.int; 354 }; 355 }); 356 value = { 357 attrs = { 358 foo = "bar"; 359 }; 360 list = [ 361 "foo" 362 "bar" 363 ]; 364 either = 123; # int 365 }; 366 testAttrs = { 367 expected = { 368 attrs = { 369 foo = "bar"; 370 }; 371 list = [ 372 "foo" 373 "bar" 374 ]; 375 either = 123; 376 }; 377 }; 378 }; 379}