lol
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 21.11-pre 730 lines 18 kB view raw
1# to run these tests: 2# nix-instantiate --eval --strict nixpkgs/lib/tests/misc.nix 3# if the resulting list is empty, all tests passed 4with import ../default.nix; 5 6let 7 8 testSanitizeDerivationName = { name, expected }: 9 let 10 drv = derivation { 11 name = strings.sanitizeDerivationName name; 12 builder = "x"; 13 system = "x"; 14 }; 15 in { 16 # Evaluate the derivation so an invalid name would be caught 17 expr = builtins.seq drv.drvPath drv.name; 18 inherit expected; 19 }; 20 21in 22 23runTests { 24 25 26# TRIVIAL 27 28 testId = { 29 expr = id 1; 30 expected = 1; 31 }; 32 33 testConst = { 34 expr = const 2 3; 35 expected = 2; 36 }; 37 38 testPipe = { 39 expr = pipe 2 [ 40 (x: x + 2) # 2 + 2 = 4 41 (x: x * 2) # 4 * 2 = 8 42 ]; 43 expected = 8; 44 }; 45 46 testPipeEmpty = { 47 expr = pipe 2 []; 48 expected = 2; 49 }; 50 51 testPipeStrings = { 52 expr = pipe [ 3 4 ] [ 53 (map toString) 54 (map (s: s + "\n")) 55 concatStrings 56 ]; 57 expected = '' 58 3 59 4 60 ''; 61 }; 62 63 /* 64 testOr = { 65 expr = or true false; 66 expected = true; 67 }; 68 */ 69 70 testAnd = { 71 expr = and true false; 72 expected = false; 73 }; 74 75 testFix = { 76 expr = fix (x: {a = if x ? a then "a" else "b";}); 77 expected = {a = "a";}; 78 }; 79 80 testComposeExtensions = { 81 expr = let obj = makeExtensible (self: { foo = self.bar; }); 82 f = self: super: { bar = false; baz = true; }; 83 g = self: super: { bar = super.baz or false; }; 84 f_o_g = composeExtensions f g; 85 composed = obj.extend f_o_g; 86 in composed.foo; 87 expected = true; 88 }; 89 90 testComposeManyExtensions0 = { 91 expr = let obj = makeExtensible (self: { foo = true; }); 92 emptyComposition = composeManyExtensions []; 93 composed = obj.extend emptyComposition; 94 in composed.foo; 95 expected = true; 96 }; 97 98 testComposeManyExtensions = 99 let f = self: super: { bar = false; baz = true; }; 100 g = self: super: { bar = super.baz or false; }; 101 h = self: super: { qux = super.bar or false; }; 102 obj = makeExtensible (self: { foo = self.qux; }); 103 in { 104 expr = let composition = composeManyExtensions [f g h]; 105 composed = obj.extend composition; 106 in composed.foo; 107 expected = (obj.extend (composeExtensions f (composeExtensions g h))).foo; 108 }; 109 110 testBitAnd = { 111 expr = (bitAnd 3 10); 112 expected = 2; 113 }; 114 115 testBitOr = { 116 expr = (bitOr 3 10); 117 expected = 11; 118 }; 119 120 testBitXor = { 121 expr = (bitXor 3 10); 122 expected = 9; 123 }; 124 125 testToHexString = { 126 expr = toHexString 250; 127 expected = "FA"; 128 }; 129 130 testToBaseDigits = { 131 expr = toBaseDigits 2 6; 132 expected = [ 1 1 0 ]; 133 }; 134 135# STRINGS 136 137 testConcatMapStrings = { 138 expr = concatMapStrings (x: x + ";") ["a" "b" "c"]; 139 expected = "a;b;c;"; 140 }; 141 142 testConcatStringsSep = { 143 expr = concatStringsSep "," ["a" "b" "c"]; 144 expected = "a,b,c"; 145 }; 146 147 testSplitStringsSimple = { 148 expr = strings.splitString "." "a.b.c.d"; 149 expected = [ "a" "b" "c" "d" ]; 150 }; 151 152 testSplitStringsEmpty = { 153 expr = strings.splitString "." "a..b"; 154 expected = [ "a" "" "b" ]; 155 }; 156 157 testSplitStringsOne = { 158 expr = strings.splitString ":" "a.b"; 159 expected = [ "a.b" ]; 160 }; 161 162 testSplitStringsNone = { 163 expr = strings.splitString "." ""; 164 expected = [ "" ]; 165 }; 166 167 testSplitStringsFirstEmpty = { 168 expr = strings.splitString "/" "/a/b/c"; 169 expected = [ "" "a" "b" "c" ]; 170 }; 171 172 testSplitStringsLastEmpty = { 173 expr = strings.splitString ":" "2001:db8:0:0042::8a2e:370:"; 174 expected = [ "2001" "db8" "0" "0042" "" "8a2e" "370" "" ]; 175 }; 176 177 testSplitStringsRegex = { 178 expr = strings.splitString "\\[{}]()^$?*+|." "A\\[{}]()^$?*+|.B"; 179 expected = [ "A" "B" ]; 180 }; 181 182 testSplitStringsDerivation = { 183 expr = take 3 (strings.splitString "/" (derivation { 184 name = "name"; 185 builder = "builder"; 186 system = "system"; 187 })); 188 expected = ["" "nix" "store"]; 189 }; 190 191 testSplitVersionSingle = { 192 expr = versions.splitVersion "1"; 193 expected = [ "1" ]; 194 }; 195 196 testSplitVersionDouble = { 197 expr = versions.splitVersion "1.2"; 198 expected = [ "1" "2" ]; 199 }; 200 201 testSplitVersionTriple = { 202 expr = versions.splitVersion "1.2.3"; 203 expected = [ "1" "2" "3" ]; 204 }; 205 206 testIsStorePath = { 207 expr = 208 let goodPath = 209 "${builtins.storeDir}/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11"; 210 in { 211 storePath = isStorePath goodPath; 212 storePathDerivation = isStorePath (import ../.. { system = "x86_64-linux"; }).hello; 213 storePathAppendix = isStorePath 214 "${goodPath}/bin/python"; 215 nonAbsolute = isStorePath (concatStrings (tail (stringToCharacters goodPath))); 216 asPath = isStorePath (/. + goodPath); 217 otherPath = isStorePath "/something/else"; 218 otherVals = { 219 attrset = isStorePath {}; 220 list = isStorePath []; 221 int = isStorePath 42; 222 }; 223 }; 224 expected = { 225 storePath = true; 226 storePathDerivation = true; 227 storePathAppendix = false; 228 nonAbsolute = false; 229 asPath = true; 230 otherPath = false; 231 otherVals = { 232 attrset = false; 233 list = false; 234 int = false; 235 }; 236 }; 237 }; 238 239# LISTS 240 241 testFilter = { 242 expr = filter (x: x != "a") ["a" "b" "c" "a"]; 243 expected = ["b" "c"]; 244 }; 245 246 testFold = 247 let 248 f = op: fold: fold op 0 (range 0 100); 249 # fold with associative operator 250 assoc = f builtins.add; 251 # fold with non-associative operator 252 nonAssoc = f builtins.sub; 253 in { 254 expr = { 255 assocRight = assoc foldr; 256 # right fold with assoc operator is same as left fold 257 assocRightIsLeft = assoc foldr == assoc foldl; 258 nonAssocRight = nonAssoc foldr; 259 nonAssocLeft = nonAssoc foldl; 260 # with non-assoc operator the fold results are not the same 261 nonAssocRightIsNotLeft = nonAssoc foldl != nonAssoc foldr; 262 # fold is an alias for foldr 263 foldIsRight = nonAssoc fold == nonAssoc foldr; 264 }; 265 expected = { 266 assocRight = 5050; 267 assocRightIsLeft = true; 268 nonAssocRight = 50; 269 nonAssocLeft = (-5050); 270 nonAssocRightIsNotLeft = true; 271 foldIsRight = true; 272 }; 273 }; 274 275 testTake = testAllTrue [ 276 ([] == (take 0 [ 1 2 3 ])) 277 ([1] == (take 1 [ 1 2 3 ])) 278 ([ 1 2 ] == (take 2 [ 1 2 3 ])) 279 ([ 1 2 3 ] == (take 3 [ 1 2 3 ])) 280 ([ 1 2 3 ] == (take 4 [ 1 2 3 ])) 281 ]; 282 283 testFoldAttrs = { 284 expr = foldAttrs (n: a: [n] ++ a) [] [ 285 { a = 2; b = 7; } 286 { a = 3; c = 8; } 287 ]; 288 expected = { a = [ 2 3 ]; b = [7]; c = [8];}; 289 }; 290 291 testSort = { 292 expr = sort builtins.lessThan [ 40 2 30 42 ]; 293 expected = [2 30 40 42]; 294 }; 295 296 testToIntShouldConvertStringToInt = { 297 expr = toInt "27"; 298 expected = 27; 299 }; 300 301 testToIntShouldThrowErrorIfItCouldNotConvertToInt = { 302 expr = builtins.tryEval (toInt "\"foo\""); 303 expected = { success = false; value = false; }; 304 }; 305 306 testHasAttrByPathTrue = { 307 expr = hasAttrByPath ["a" "b"] { a = { b = "yey"; }; }; 308 expected = true; 309 }; 310 311 testHasAttrByPathFalse = { 312 expr = hasAttrByPath ["a" "b"] { a = { c = "yey"; }; }; 313 expected = false; 314 }; 315 316 317# ATTRSETS 318 319 # code from the example 320 testRecursiveUpdateUntil = { 321 expr = recursiveUpdateUntil (path: l: r: path == ["foo"]) { 322 # first attribute set 323 foo.bar = 1; 324 foo.baz = 2; 325 bar = 3; 326 } { 327 #second attribute set 328 foo.bar = 1; 329 foo.quz = 2; 330 baz = 4; 331 }; 332 expected = { 333 foo.bar = 1; # 'foo.*' from the second set 334 foo.quz = 2; # 335 bar = 3; # 'bar' from the first set 336 baz = 4; # 'baz' from the second set 337 }; 338 }; 339 340 testOverrideExistingEmpty = { 341 expr = overrideExisting {} { a = 1; }; 342 expected = {}; 343 }; 344 345 testOverrideExistingDisjoint = { 346 expr = overrideExisting { b = 2; } { a = 1; }; 347 expected = { b = 2; }; 348 }; 349 350 testOverrideExistingOverride = { 351 expr = overrideExisting { a = 3; b = 2; } { a = 1; }; 352 expected = { a = 1; b = 2; }; 353 }; 354 355# GENERATORS 356# these tests assume attributes are converted to lists 357# in alphabetical order 358 359 testMkKeyValueDefault = { 360 expr = generators.mkKeyValueDefault {} ":" "f:oo" "bar"; 361 expected = ''f\:oo:bar''; 362 }; 363 364 testMkValueString = { 365 expr = let 366 vals = { 367 int = 42; 368 string = ''fo"o''; 369 bool = true; 370 bool2 = false; 371 null = null; 372 # float = 42.23; # floats are strange 373 }; 374 in mapAttrs 375 (const (generators.mkValueStringDefault {})) 376 vals; 377 expected = { 378 int = "42"; 379 string = ''fo"o''; 380 bool = "true"; 381 bool2 = "false"; 382 null = "null"; 383 # float = "42.23" true false [ "bar" ] ]''; 384 }; 385 }; 386 387 testToKeyValue = { 388 expr = generators.toKeyValue {} { 389 key = "value"; 390 "other=key" = "baz"; 391 }; 392 expected = '' 393 key=value 394 other\=key=baz 395 ''; 396 }; 397 398 testToINIEmpty = { 399 expr = generators.toINI {} {}; 400 expected = ""; 401 }; 402 403 testToINIEmptySection = { 404 expr = generators.toINI {} { foo = {}; bar = {}; }; 405 expected = '' 406 [bar] 407 408 [foo] 409 ''; 410 }; 411 412 testToINIDuplicateKeys = { 413 expr = generators.toINI { listsAsDuplicateKeys = true; } { foo.bar = true; baz.qux = [ 1 false ]; }; 414 expected = '' 415 [baz] 416 qux=1 417 qux=false 418 419 [foo] 420 bar=true 421 ''; 422 }; 423 424 testToINIDefaultEscapes = { 425 expr = generators.toINI {} { 426 "no [ and ] allowed unescaped" = { 427 "and also no = in keys" = 42; 428 }; 429 }; 430 expected = '' 431 [no \[ and \] allowed unescaped] 432 and also no \= in keys=42 433 ''; 434 }; 435 436 testToINIDefaultFull = { 437 expr = generators.toINI {} { 438 "section 1" = { 439 attribute1 = 5; 440 x = "Me-se JarJar Binx"; 441 # booleans are converted verbatim by default 442 boolean = false; 443 }; 444 "foo[]" = { 445 "he\\h=he" = "this is okay"; 446 }; 447 }; 448 expected = '' 449 [foo\[\]] 450 he\h\=he=this is okay 451 452 [section 1] 453 attribute1=5 454 boolean=false 455 x=Me-se JarJar Binx 456 ''; 457 }; 458 459 /* right now only invocation check */ 460 testToJSONSimple = 461 let val = { 462 foobar = [ "baz" 1 2 3 ]; 463 }; 464 in { 465 expr = generators.toJSON {} val; 466 # trivial implementation 467 expected = builtins.toJSON val; 468 }; 469 470 /* right now only invocation check */ 471 testToYAMLSimple = 472 let val = { 473 list = [ { one = 1; } { two = 2; } ]; 474 all = 42; 475 }; 476 in { 477 expr = generators.toYAML {} val; 478 # trivial implementation 479 expected = builtins.toJSON val; 480 }; 481 482 testToPretty = 483 let 484 deriv = derivation { name = "test"; builder = "/bin/sh"; system = builtins.currentSystem; }; 485 in { 486 expr = mapAttrs (const (generators.toPretty { multiline = false; })) rec { 487 int = 42; 488 float = 0.1337; 489 bool = true; 490 emptystring = ""; 491 string = ''fno"rd''; 492 newlinestring = "\n"; 493 path = /. + "/foo"; 494 null_ = null; 495 function = x: x; 496 functionArgs = { arg ? 4, foo }: arg; 497 list = [ 3 4 function [ false ] ]; 498 emptylist = []; 499 attrs = { foo = null; "foo bar" = "baz"; }; 500 emptyattrs = {}; 501 drv = deriv; 502 }; 503 expected = rec { 504 int = "42"; 505 float = "~0.133700"; 506 bool = "true"; 507 emptystring = ''""''; 508 string = ''"fno\"rd"''; 509 newlinestring = "\"\\n\""; 510 path = "/foo"; 511 null_ = "null"; 512 function = "<function>"; 513 functionArgs = "<function, args: {arg?, foo}>"; 514 list = "[ 3 4 ${function} [ false ] ]"; 515 emptylist = "[ ]"; 516 attrs = "{ foo = null; \"foo bar\" = \"baz\"; }"; 517 emptyattrs = "{ }"; 518 drv = "<derivation ${deriv.drvPath}>"; 519 }; 520 }; 521 522 testToPrettyMultiline = { 523 expr = mapAttrs (const (generators.toPretty { })) rec { 524 list = [ 3 4 [ false ] ]; 525 attrs = { foo = null; bar.foo = "baz"; }; 526 newlinestring = "\n"; 527 multilinestring = '' 528 hello 529 there 530 test 531 ''; 532 multilinestring' = '' 533 hello 534 there 535 test''; 536 }; 537 expected = rec { 538 list = '' 539 [ 540 3 541 4 542 [ 543 false 544 ] 545 ]''; 546 attrs = '' 547 { 548 bar = { 549 foo = "baz"; 550 }; 551 foo = null; 552 }''; 553 newlinestring = "''\n \n''"; 554 multilinestring = '' 555 ''' 556 hello 557 there 558 test 559 '''''; 560 multilinestring' = '' 561 ''' 562 hello 563 there 564 test'''''; 565 566 }; 567 }; 568 569 testToPrettyAllowPrettyValues = { 570 expr = generators.toPretty { allowPrettyValues = true; } 571 { __pretty = v: "«" + v + "»"; val = "foo"; }; 572 expected = "«foo»"; 573 }; 574 575 576# CLI 577 578 testToGNUCommandLine = { 579 expr = cli.toGNUCommandLine {} { 580 data = builtins.toJSON { id = 0; }; 581 X = "PUT"; 582 retry = 3; 583 retry-delay = null; 584 url = [ "https://example.com/foo" "https://example.com/bar" ]; 585 silent = false; 586 verbose = true; 587 }; 588 589 expected = [ 590 "-X" "PUT" 591 "--data" "{\"id\":0}" 592 "--retry" "3" 593 "--url" "https://example.com/foo" 594 "--url" "https://example.com/bar" 595 "--verbose" 596 ]; 597 }; 598 599 testToGNUCommandLineShell = { 600 expr = cli.toGNUCommandLineShell {} { 601 data = builtins.toJSON { id = 0; }; 602 X = "PUT"; 603 retry = 3; 604 retry-delay = null; 605 url = [ "https://example.com/foo" "https://example.com/bar" ]; 606 silent = false; 607 verbose = true; 608 }; 609 610 expected = "'-X' 'PUT' '--data' '{\"id\":0}' '--retry' '3' '--url' 'https://example.com/foo' '--url' 'https://example.com/bar' '--verbose'"; 611 }; 612 613 testSanitizeDerivationNameLeadingDots = testSanitizeDerivationName { 614 name = "..foo"; 615 expected = "foo"; 616 }; 617 618 testSanitizeDerivationNameAscii = testSanitizeDerivationName { 619 name = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; 620 expected = "-+--.-0123456789-=-?-ABCDEFGHIJKLMNOPQRSTUVWXYZ-_-abcdefghijklmnopqrstuvwxyz-"; 621 }; 622 623 testSanitizeDerivationNameTooLong = testSanitizeDerivationName { 624 name = "This string is loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"; 625 expected = "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"; 626 }; 627 628 testSanitizeDerivationNameTooLongWithInvalid = testSanitizeDerivationName { 629 name = "Hello there aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&&&&&&&"; 630 expected = "there-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-"; 631 }; 632 633 testSanitizeDerivationNameEmpty = testSanitizeDerivationName { 634 name = ""; 635 expected = "unknown"; 636 }; 637 638 testFreeformOptions = { 639 expr = 640 let 641 submodule = { lib, ... }: { 642 freeformType = lib.types.attrsOf (lib.types.submodule { 643 options.bar = lib.mkOption {}; 644 }); 645 options.bar = lib.mkOption {}; 646 }; 647 648 module = { lib, ... }: { 649 options.foo = lib.mkOption { 650 type = lib.types.submodule submodule; 651 }; 652 }; 653 654 options = (evalModules { 655 modules = [ module ]; 656 }).options; 657 658 locs = filter (o: ! o.internal) (optionAttrSetToDocList options); 659 in map (o: o.loc) locs; 660 expected = [ [ "foo" ] [ "foo" "<name>" "bar" ] [ "foo" "bar" ] ]; 661 }; 662 663 testCartesianProductOfEmptySet = { 664 expr = cartesianProductOfSets {}; 665 expected = [ {} ]; 666 }; 667 668 testCartesianProductOfOneSet = { 669 expr = cartesianProductOfSets { a = [ 1 2 3 ]; }; 670 expected = [ { a = 1; } { a = 2; } { a = 3; } ]; 671 }; 672 673 testCartesianProductOfTwoSets = { 674 expr = cartesianProductOfSets { a = [ 1 ]; b = [ 10 20 ]; }; 675 expected = [ 676 { a = 1; b = 10; } 677 { a = 1; b = 20; } 678 ]; 679 }; 680 681 testCartesianProductOfTwoSetsWithOneEmpty = { 682 expr = cartesianProductOfSets { a = [ ]; b = [ 10 20 ]; }; 683 expected = [ ]; 684 }; 685 686 testCartesianProductOfThreeSets = { 687 expr = cartesianProductOfSets { 688 a = [ 1 2 3 ]; 689 b = [ 10 20 30 ]; 690 c = [ 100 200 300 ]; 691 }; 692 expected = [ 693 { a = 1; b = 10; c = 100; } 694 { a = 1; b = 10; c = 200; } 695 { a = 1; b = 10; c = 300; } 696 697 { a = 1; b = 20; c = 100; } 698 { a = 1; b = 20; c = 200; } 699 { a = 1; b = 20; c = 300; } 700 701 { a = 1; b = 30; c = 100; } 702 { a = 1; b = 30; c = 200; } 703 { a = 1; b = 30; c = 300; } 704 705 { a = 2; b = 10; c = 100; } 706 { a = 2; b = 10; c = 200; } 707 { a = 2; b = 10; c = 300; } 708 709 { a = 2; b = 20; c = 100; } 710 { a = 2; b = 20; c = 200; } 711 { a = 2; b = 20; c = 300; } 712 713 { a = 2; b = 30; c = 100; } 714 { a = 2; b = 30; c = 200; } 715 { a = 2; b = 30; c = 300; } 716 717 { a = 3; b = 10; c = 100; } 718 { a = 3; b = 10; c = 200; } 719 { a = 3; b = 10; c = 300; } 720 721 { a = 3; b = 20; c = 100; } 722 { a = 3; b = 20; c = 200; } 723 { a = 3; b = 20; c = 300; } 724 725 { a = 3; b = 30; c = 100; } 726 { a = 3; b = 30; c = 200; } 727 { a = 3; b = 30; c = 300; } 728 ]; 729 }; 730}