fork
Configure Feed
Select the types of activity you want to include in your feed.
lol
fork
Configure Feed
Select the types of activity you want to include in your feed.
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}