1with builtins;
2let
3 /*
4 underTest = {
5 x = {
6 a = 1;
7 b = "2";
8 };
9 };
10
11 tests = [
12 (root: false)
13 {
14 x = [
15 (set: true)
16 {
17 a = (a: a > 1);
18 b = (b: b == "3");
19 }
20 ];
21 }
22 ];
23
24 results = run "Examples" underTest tests;
25 */
26
27 passed = desc: {
28 result = "pass";
29 description = desc;
30 };
31
32 failed = desc: {
33 result = "failed";
34 description = desc;
35 };
36
37 prefixName = name: res: {
38 inherit (res) result;
39 description = "${name}: ${res.description}";
40 };
41
42 run = name: under: tests: if isList tests then
43 (concatLists (map (run name under) tests))
44 else if isAttrs tests then
45 (concatLists (map (
46 subName: run (name + "." + subName) (if hasAttr subName under then getAttr subName under else "<MISSING!>") (getAttr subName tests)
47 ) (attrNames tests)))
48 else if isFunction tests then
49 let
50 res = tests under;
51 in
52 if isBool res then
53 [
54 (prefixName name (if tests under then passed "passed" else failed "failed"))
55 ]
56 else
57 [ (prefixName name res) ]
58 else [
59 failed (name ": not a function, list or set")
60 ];
61in
62 { inherit run passed failed; }