diff --git a/checkmate/modules/tests.nix b/checkmate/modules/tests.nix index 2a7e30a..6ec6aa9 100644 --- a/checkmate/modules/tests.nix +++ b/checkmate/modules/tests.nix @@ -1,518 +1,67 @@ -{ inputs, ... }: -{ - perSystem = - { lib, ... }: - let - transpose = import ../../nix { inherit lib; }; - - mkFlake = - mod: - inputs.flake-parts.lib.mkFlake - { - inputs.self = [ ]; - } - { - systems = [ ]; - imports = [ - ../../nix/flakeModule.nix - inputs.flake-parts.flakeModules.modules - mod - (fooMod "aspectOne") - (fooMod "aspectTwo") - (fooMod "aspectThree") - ]; - }; - - fooMod = aspect: { +{ inputs, lib, ... }: +let + targetNix = "${inputs.target}/nix"; + targetLib = "${inputs.target}/nix/lib.nix"; + targetMod = "${inputs.target}/nix/flakeModule.nix"; + + transpose = import targetNix { inherit lib; }; + + mkFlake = + mod: + inputs.flake-parts.lib.mkFlake + { + inputs.self = [ ]; + } + { + systems = [ ]; imports = [ - { flake.modules.classOne.${aspect}.imports = [ fooOpt ]; } - { flake.modules.classTwo.${aspect}.imports = [ fooOpt ]; } - { flake.modules.classThree.${aspect}.imports = [ fooOpt ]; } + targetMod + inputs.flake-parts.flakeModules.modules + mod + (fooMod "aspectOne") + (fooMod "aspectTwo") + (fooMod "aspectThree") ]; }; - fooOpt = { - options.foo = lib.mkOption { - type = lib.types.str; - default = ""; - }; - options.bar = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - }; - options.baz = lib.mkOption { - type = lib.types.lazyAttrsOf lib.types.str; - default = { }; - }; - }; - - evalMod = - class: mod: - (lib.evalModules { - inherit class; - modules = [ mod ]; - }).config; - in - { - nix-unit.tests = { - transpose."test swaps parent and child attrNames" = { - expr = transpose { a.b.c = 1; }; - expected = { - b.a.c = 1; - }; - }; - - transpose."test common childs become one parent" = { - expr = transpose { - a.b = 1; - c.b = 2; - }; - expected.b = { - a = 1; - c = 2; - }; - }; - - new-scope."test usage without flakes" = - let - flake-aspects-lib = import ../../nix/lib.nix lib; - # first eval is like evaling the flake. - first = lib.evalModules { - modules = [ - (flake-aspects-lib.new-scope "hello") - { - hello.aspects = - { aspects, ... }: - { - a.b.c = [ "world" ]; - a.includes = [ aspects.x ]; - x.b = - { lib, ... }: - { - c = lib.splitString " " "mundo cruel"; - }; - }; - } - ]; - }; - # second eval is like evaling its nixosConfiguration - second = lib.evalModules { - modules = [ - { options.c = lib.mkOption { type = lib.types.listOf lib.types.str; }; } - first.config.hello.modules.b.a - ]; - }; - expr = lib.sort (a: b: a < b) second.config.c; - expected = [ - "cruel" - "mundo" - "world" - ]; - in - { - inherit expr expected; - }; - - aspects."test provides default" = - let - flake = - inputs.flake-parts.lib.mkFlake - { - inputs.self = [ ]; - moduleLocation = builtins.toString ./.; - } - { - systems = [ ]; - imports = [ - ../../nix/flakeModule.nix - inputs.flake-parts.flakeModules.modules - ]; - }; - expr = flake.modules; - expected = { }; - in - { - inherit expr expected; - }; - - aspects."test transposes to flake.modules" = - let - flake = mkFlake { - flake.aspects.aspectOne = { - classOne.foo = "niri"; - classTwo.foo = "paper.spoon"; - }; - }; - expr = { - classOne = (evalMod "classOne" flake.modules.classOne.aspectOne).foo; - classTwo = (evalMod "classTwo" flake.modules.classTwo.aspectOne).foo; - }; - expected = { - classOne = "niri"; - classTwo = "paper.spoon"; - }; - in - { - inherit expr expected; - }; - - aspects."test dependencies on aspects" = - let - flake = mkFlake { - flake.aspects = - { aspects, ... }: - { - aspectOne = { - description = "os config"; - includes = with aspects; [ aspectTwo ]; - classOne.bar = [ "os" ]; - }; - - aspectTwo = { - description = "user config at os level"; - classOne.bar = [ "user" ]; - }; - }; - }; - expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar; - expected = [ - "os" - "user" - ]; - in - { - inherit expr expected; - }; - - aspects."test resolve aspect-chain" = - let - flake = mkFlake { - flake.aspects = - { aspects, ... }: - { - aspectOne = { - name = "one"; - includes = [ aspects.aspectOne.provides.dos ]; - classOne.bar = [ "zzz" ]; - provides.dos = - { aspect-chain, ... }: - { - name = "dos"; - includes = [ aspects.aspectOne.provides.tres ]; - classOne.bar = map (x: x.name) aspect-chain; - }; - - provides.tres = - { aspect-chain, ... }: - { - name = "tres"; - classOne.bar = [ (lib.last aspect-chain).name ]; - }; - }; - }; - }; - mod = { - imports = [ - fooOpt - (flake.aspects.aspectOne.resolve { class = "classOne"; }) - ]; - }; - expr = lib.sort (a: b: a < b) (evalMod "classOne" mod).bar; - expected = [ - "dos" - "one" - "zzz" - ]; - in - { - inherit expr expected; - }; - - aspects."test modules resolved" = - let - flake = mkFlake { - flake.aspects = - { aspects, ... }: - { - aspectOne = { - name = "one"; - includes = [ aspects.aspectOne.provides.dos ]; - classOne.bar = [ "zzz" ]; - provides.dos = - { aspect-chain, ... }: - { - name = "dos"; - includes = [ aspects.aspectOne.provides.tres ]; - classOne.bar = map (x: x.name) aspect-chain; - }; - - provides.tres = - { aspect-chain, ... }: - { - name = "tres"; - classOne.bar = [ (lib.last aspect-chain).name ]; - }; - }; - }; - }; - mod = { - imports = [ - fooOpt - (flake.aspects.aspectOne.modules.classOne) - ]; - }; - expr = lib.sort (a: b: a < b) (evalMod "classOne" mod).bar; - expected = [ - "dos" - "one" - "zzz" - ]; - in - { - inherit expr expected; - }; - - aspects."test provides" = - let - flake = mkFlake { - flake.aspects = - { aspects, ... }: - { - aspectOne.includes = with aspects.aspectTwo.provides; [ - foo - bar - ]; - aspectOne.classOne = { }; # must be present for mixing dependencies. - aspectTwo = { - classOne.bar = [ "class one not included" ]; - classTwo.bar = [ "class two not included" ]; - provides.foo = - { class, aspect-chain }: - { - name = "aspectTwo.foo"; - description = "aspectTwo foo provided"; - includes = [ - aspects.aspectThree.provides.moo - aspects.aspectTwo.provides.baz - ]; - classOne.bar = [ "two:${class}:${lib.concatStringsSep "/" (lib.map (x: x.name) aspect-chain)}" ]; - classTwo.bar = [ "foo class two not included" ]; - }; - # a provider can be immediately an aspect object. - provides.bar = { - # classOne is missing on bar - classTwo.bar = [ "bar class two not included" ]; - }; - # _ is an shortcut alias of provides. - _.baz = { - # classOne is missing on bar - classTwo.bar = [ "baz" ]; - }; - }; - aspectThree.provides.moo = - { aspect-chain, class }: - { - classOne.bar = [ "three:${class}:${lib.concatStringsSep "/" (lib.map (x: x.name) aspect-chain)}" ]; - }; - }; - }; - expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar; - expected = [ - "three:classOne:aspectOne/aspectTwo.foo" - "two:classOne:aspectOne" - ]; - in - { - inherit expr expected; - }; - - aspects."test provides using fixpoints" = - let - flake = mkFlake { - flake.aspects = - { aspects, ... }: - { - aspectOne = { - classOne.bar = [ "1" ]; - includes = [ - aspects.aspectTwo - ]; - }; - - aspectTwo = { - classOne.bar = [ "2" ]; - includes = [ aspects.aspectTwo.provides.three-and-four-and-five ]; - provides = - { provides, ... }: - { - three-and-four-and-five = { - classOne.bar = [ "3" ]; - includes = [ - provides.four - aspects.five - ]; - }; - four = { - classOne.bar = [ "4" ]; - }; - }; - }; - - five.classOne.bar = [ "5" ]; - }; - }; - - expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar; - expected = [ - "1" - "2" - "3" - "4" - "5" - ]; - in - { - inherit expr expected; - }; - - aspects."test provides parametrized modules" = - let - flake = mkFlake { - flake.aspects = - { aspects, ... }: - { - aspectOne.includes = [ (aspects.aspectTwo.provides.hello "mundo") ]; - aspectOne.classOne.bar = [ "1" ]; - - aspectTwo.provides.hello = world: { - classOne.bar = [ world ]; - }; - }; - }; - - expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar; - expected = [ - "1" - "mundo" - ]; - in - { - inherit expr expected; - }; - - aspects."test override default provider" = - let - flake = mkFlake { - flake.aspects = - { aspects, ... }: - { - aspectOne = - { aspect, ... }: - { - includes = [ (aspects.aspectTwo { message = "hello ${aspect.name}"; }) ]; - classOne = { }; # required for propagation - }; - - aspectTwo.__functor = - _: - { message }: # args must be always named - { class, aspect-chain }: - { aspect, ... }: - { - classOne.bar = [ - "foo" - aspect.name - message - class - ] - ++ (lib.map (x: x.name) aspect-chain); - }; - aspectTwo.classOne.bar = [ "itself not included" ]; - }; - }; - - expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar; - expected = [ - "foo" - "" - "hello aspectOne" - "classOne" - "aspectOne" - ]; - in - { - inherit expr expected; - }; - - aspects."test override default provider includes" = - let - flake = mkFlake { - flake.aspects = - { aspects, ... }: - { - aspectOne = { - classOne.bar = [ "should-not-be-present" ]; - includes = [ aspects.aspectTwo ]; - __functor = aspect: { - includes = [ - { classOne.bar = [ "from-functor" ]; } - ] - ++ map (f: f { message = "hello"; }) aspect.includes; - }; - }; - aspectTwo.__functor = - _aspect: - { message }: - { - classOne.bar = [ message ]; - }; - }; - }; - - expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar; - expected = [ - "hello" - "from-functor" - ]; - in - { - inherit expr expected; - }; - - aspects."test define top-level context-aware aspect" = - let - flake = mkFlake { - flake.aspects = - { aspects, ... }: - { - aspectOne = { - classOne.bar = [ "should-not-be-present" ]; - includes = [ aspects.aspectTwo ]; - __functor = aspect: { - includes = [ - { classOne.bar = [ "from-functor" ]; } - ] - ++ map (f: f { message = "hello"; }) aspect.includes; - }; - }; - aspectTwo = - { message }: - { - classOne.bar = [ message ]; - }; - }; - }; - - expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar; - expected = [ - "hello" - "from-functor" - ]; - in - { - inherit expr expected; - }; - }; - + fooMod = aspect: { + imports = [ + { flake.modules.classOne.${aspect}.imports = [ fooOpt ]; } + { flake.modules.classTwo.${aspect}.imports = [ fooOpt ]; } + { flake.modules.classThree.${aspect}.imports = [ fooOpt ]; } + ]; + }; + + fooOpt = { + options.foo = lib.mkOption { + type = lib.types.str; + default = ""; + }; + options.bar = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; }; + options.baz = lib.mkOption { + type = lib.types.lazyAttrsOf lib.types.str; + default = { }; + }; + }; + + evalMod = + class: mod: + (lib.evalModules { + inherit class; + modules = [ mod ]; + }).config; +in +{ + _module.args = { + inherit + transpose + targetLib + targetMod + targetNix + ; + inherit mkFlake evalMod fooOpt; + }; } diff --git a/checkmate/modules/tests/aspect_chain.nix b/checkmate/modules/tests/aspect_chain.nix new file mode 100644 index 0000000..54d5503 --- /dev/null +++ b/checkmate/modules/tests/aspect_chain.nix @@ -0,0 +1,53 @@ +{ + lib, + mkFlake, + evalMod, + fooOpt, + ... +}: +{ + + flake.tests."test resolve aspect-chain" = + let + flake = mkFlake { + flake.aspects = + { aspects, ... }: + { + aspectOne = { + name = "one"; + includes = [ aspects.aspectOne.provides.dos ]; + classOne.bar = [ "zzz" ]; + provides.dos = + { aspect-chain, ... }: + { + name = "dos"; + includes = [ aspects.aspectOne.provides.tres ]; + classOne.bar = map (x: x.name) aspect-chain; + }; + + provides.tres = + { aspect-chain, ... }: + { + name = "tres"; + classOne.bar = [ (lib.last aspect-chain).name ]; + }; + }; + }; + }; + mod = { + imports = [ + fooOpt + (flake.aspects.aspectOne.resolve { class = "classOne"; }) + ]; + }; + expr = lib.sort (a: b: a < b) (evalMod "classOne" mod).bar; + expected = [ + "dos" + "one" + "zzz" + ]; + in + { + inherit expr expected; + }; +} diff --git a/checkmate/modules/tests/aspect_default_provider_functor.nix b/checkmate/modules/tests/aspect_default_provider_functor.nix new file mode 100644 index 0000000..76b20d2 --- /dev/null +++ b/checkmate/modules/tests/aspect_default_provider_functor.nix @@ -0,0 +1,53 @@ +{ + mkFlake, + evalMod, + lib, + ... +}: +{ + + flake.tests."test override default provider" = + let + flake = mkFlake { + flake.aspects = + { aspects, ... }: + { + aspectOne = + { aspect, ... }: + { + includes = [ (aspects.aspectTwo { message = "hello ${aspect.name}"; }) ]; + classOne = { }; # required for propagation + }; + + aspectTwo.__functor = + _: + { message }: # args must be always named + { class, aspect-chain }: + { aspect, ... }: + { + classOne.bar = [ + "foo" + aspect.name + message + class + ] + ++ (lib.map (x: x.name) aspect-chain); + }; + aspectTwo.classOne.bar = [ "itself not included" ]; + }; + }; + + expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar; + expected = [ + "foo" + "" + "hello aspectOne" + "classOne" + "aspectOne" + ]; + in + { + inherit expr expected; + }; + +} diff --git a/checkmate/modules/tests/aspect_default_provider_override.nix b/checkmate/modules/tests/aspect_default_provider_override.nix new file mode 100644 index 0000000..b9abad6 --- /dev/null +++ b/checkmate/modules/tests/aspect_default_provider_override.nix @@ -0,0 +1,42 @@ +{ + mkFlake, + evalMod, + ... +}: +{ + + flake.tests."test override default provider includes" = + let + flake = mkFlake { + flake.aspects = + { aspects, ... }: + { + aspectOne = { + classOne.bar = [ "should-not-be-present" ]; + includes = [ aspects.aspectTwo ]; + __functor = aspect: { + includes = [ + { classOne.bar = [ "from-functor" ]; } + ] + ++ map (f: f { message = "hello"; }) aspect.includes; + }; + }; + aspectTwo.__functor = + _aspect: + { message }: + { + classOne.bar = [ message ]; + }; + }; + }; + + expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar; + expected = [ + "hello" + "from-functor" + ]; + in + { + inherit expr expected; + }; +} diff --git a/checkmate/modules/tests/aspect_dependencies.nix b/checkmate/modules/tests/aspect_dependencies.nix new file mode 100644 index 0000000..c8423c9 --- /dev/null +++ b/checkmate/modules/tests/aspect_dependencies.nix @@ -0,0 +1,37 @@ +{ + mkFlake, + evalMod, + lib, + ... +}: +{ + + flake.tests."test dependencies on aspects" = + let + flake = mkFlake { + flake.aspects = + { aspects, ... }: + { + aspectOne = { + description = "os config"; + includes = with aspects; [ aspectTwo ]; + classOne.bar = [ "os" ]; + }; + + aspectTwo = { + description = "user config at os level"; + classOne.bar = [ "user" ]; + }; + }; + }; + expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar; + expected = [ + "os" + "user" + ]; + in + { + inherit expr expected; + }; + +} diff --git a/checkmate/modules/tests/aspect_fixpoint.nix b/checkmate/modules/tests/aspect_fixpoint.nix new file mode 100644 index 0000000..de0ac0e --- /dev/null +++ b/checkmate/modules/tests/aspect_fixpoint.nix @@ -0,0 +1,58 @@ +{ + lib, + mkFlake, + evalMod, + ... +}: +{ + + flake.tests."test provides using fixpoints" = + let + flake = mkFlake { + flake.aspects = + { aspects, ... }@top: + { + aspectOne = { + classOne.bar = [ "1" ]; + includes = [ + aspects.aspectTwo + ]; + }; + + aspectTwo = { + classOne.bar = [ "2" ]; + includes = [ aspects.aspectTwo.provides.three-and-four-and-five ]; + provides = + { aspects, ... }: + { + three-and-four-and-five = { + classOne.bar = [ "3" ]; + includes = [ + aspects.four + top.aspects.five + ]; + }; + four = { + classOne.bar = [ "4" ]; + }; + }; + }; + + five.classOne.bar = [ "5" ]; + }; + }; + + expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar; + expected = [ + "1" + "2" + "3" + "4" + "5" + ]; + in + { + inherit expr expected; + }; + +} diff --git a/checkmate/modules/tests/aspect_modules_resolved.nix b/checkmate/modules/tests/aspect_modules_resolved.nix new file mode 100644 index 0000000..7086567 --- /dev/null +++ b/checkmate/modules/tests/aspect_modules_resolved.nix @@ -0,0 +1,54 @@ +{ + lib, + mkFlake, + evalMod, + fooOpt, + ... +}: +{ + + flake.tests."test modules resolved" = + let + flake = mkFlake { + flake.aspects = + { aspects, ... }: + { + aspectOne = { + name = "one"; + includes = [ aspects.aspectOne.provides.dos ]; + classOne.bar = [ "zzz" ]; + provides.dos = + { aspect-chain, ... }: + { + name = "dos"; + includes = [ aspects.aspectOne.provides.tres ]; + classOne.bar = map (x: x.name) aspect-chain; + }; + + provides.tres = + { aspect-chain, ... }: + { + name = "tres"; + classOne.bar = [ (lib.last aspect-chain).name ]; + }; + }; + }; + }; + mod = { + imports = [ + fooOpt + (flake.aspects.aspectOne.modules.classOne) + ]; + }; + expr = lib.sort (a: b: a < b) (evalMod "classOne" mod).bar; + expected = [ + "dos" + "one" + "zzz" + ]; + in + { + inherit expr expected; + }; + +} diff --git a/checkmate/modules/tests/aspect_parametric.nix b/checkmate/modules/tests/aspect_parametric.nix new file mode 100644 index 0000000..b99d9b5 --- /dev/null +++ b/checkmate/modules/tests/aspect_parametric.nix @@ -0,0 +1,34 @@ +{ + mkFlake, + evalMod, + lib, + ... +}: +{ + + flake.tests."test provides parametrized modules" = + let + flake = mkFlake { + flake.aspects = + { aspects, ... }: + { + aspectOne.includes = [ (aspects.aspectTwo.provides.hello "mundo") ]; + aspectOne.classOne.bar = [ "1" ]; + + aspectTwo.provides.hello = world: { + classOne.bar = [ world ]; + }; + }; + }; + + expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar; + expected = [ + "1" + "mundo" + ]; + in + { + inherit expr expected; + }; + +} diff --git a/checkmate/modules/tests/aspect_provides.nix b/checkmate/modules/tests/aspect_provides.nix new file mode 100644 index 0000000..d4c8039 --- /dev/null +++ b/checkmate/modules/tests/aspect_provides.nix @@ -0,0 +1,63 @@ +{ + lib, + mkFlake, + evalMod, + ... +}: +{ + + flake.tests."test provides" = + let + flake = mkFlake { + flake.aspects = + { aspects, ... }: + { + aspectOne.includes = with aspects.aspectTwo.provides; [ + foo + bar + ]; + aspectOne.classOne = { }; # must be present for mixing dependencies. + aspectTwo = { + classOne.bar = [ "class one not included" ]; + classTwo.bar = [ "class two not included" ]; + provides.foo = + { class, aspect-chain }: + { + name = "aspectTwo.foo"; + description = "aspectTwo foo provided"; + includes = [ + aspects.aspectThree.provides.moo + aspects.aspectTwo.provides.baz + ]; + classOne.bar = [ "two:${class}:${lib.concatStringsSep "/" (lib.map (x: x.name) aspect-chain)}" ]; + classTwo.bar = [ "foo class two not included" ]; + }; + # a provider can be immediately an aspect object. + provides.bar = { + # classOne is missing on bar + classTwo.bar = [ "bar class two not included" ]; + }; + # _ is an shortcut alias of provides. + _.baz = { + # classOne is missing on bar + classTwo.bar = [ "baz" ]; + }; + }; + aspectThree.provides.moo = + { aspect-chain, class }: + { + classOne.bar = [ "three:${class}:${lib.concatStringsSep "/" (lib.map (x: x.name) aspect-chain)}" ]; + }; + }; + }; + expr = lib.sort (a: b: a < b) (evalMod "classOne" flake.modules.classOne.aspectOne).bar; + expected = [ + "three:classOne:aspectOne/aspectTwo.foo" + "two:classOne:aspectOne" + ]; + in + { + inherit expr expected; + }; + +} diff --git a/checkmate/modules/tests/aspect_toplevel_parametric.nix b/checkmate/modules/tests/aspect_toplevel_parametric.nix new file mode 100644 index 0000000..b64fc33 --- /dev/null +++ b/checkmate/modules/tests/aspect_toplevel_parametric.nix @@ -0,0 +1,41 @@ +{ + mkFlake, + evalMod, + ... +}: +{ + + flake.tests."test define top-level context-aware aspect" = + let + flake = mkFlake { + flake.aspects = + { aspects, ... }: + { + aspectOne = { + classOne.bar = [ "should-not-be-present" ]; + includes = [ aspects.aspectTwo ]; + __functor = aspect: { + includes = [ + { classOne.bar = [ "from-functor" ]; } + ] + ++ map (f: f { message = "hello"; }) aspect.includes; + }; + }; + aspectTwo = + { message }: + { + classOne.bar = [ message ]; + }; + }; + }; + + expr = (evalMod "classOne" flake.modules.classOne.aspectOne).bar; + expected = [ + "hello" + "from-functor" + ]; + in + { + inherit expr expected; + }; +} diff --git a/checkmate/modules/tests/default_empty.nix b/checkmate/modules/tests/default_empty.nix new file mode 100644 index 0000000..94abe3d --- /dev/null +++ b/checkmate/modules/tests/default_empty.nix @@ -0,0 +1,29 @@ +{ + inputs, + targetMod, + ... +}: +{ + + flake.tests."test provides default" = + let + flake = + inputs.flake-parts.lib.mkFlake + { + inputs.self = [ ]; + moduleLocation = builtins.toString ./.; + } + { + systems = [ ]; + imports = [ + targetMod + inputs.flake-parts.flakeModules.modules + ]; + }; + expr = flake.modules; + expected = { }; + in + { + inherit expr expected; + }; +} diff --git a/checkmate/modules/tests/tranpose_flake_modules.nix b/checkmate/modules/tests/tranpose_flake_modules.nix new file mode 100644 index 0000000..22c5509 --- /dev/null +++ b/checkmate/modules/tests/tranpose_flake_modules.nix @@ -0,0 +1,28 @@ +{ + mkFlake, + evalMod, + ... +}: +{ + + flake.tests."test transposes to flake.modules" = + let + flake = mkFlake { + flake.aspects.aspectOne = { + classOne.foo = "niri"; + classTwo.foo = "paper.spoon"; + }; + }; + expr = { + classOne = (evalMod "classOne" flake.modules.classOne.aspectOne).foo; + classTwo = (evalMod "classTwo" flake.modules.classTwo.aspectOne).foo; + }; + expected = { + classOne = "niri"; + classTwo = "paper.spoon"; + }; + in + { + inherit expr expected; + }; +} diff --git a/checkmate/modules/tests/transpose_common.nix b/checkmate/modules/tests/transpose_common.nix new file mode 100644 index 0000000..25f03d3 --- /dev/null +++ b/checkmate/modules/tests/transpose_common.nix @@ -0,0 +1,15 @@ +{ transpose, ... }: +{ + + flake.tests."test transpose common childs become one parent" = { + expr = transpose { + a.b = 1; + c.b = 2; + }; + expected.b = { + a = 1; + c = 2; + }; + }; + +} diff --git a/checkmate/modules/tests/transpose_swap.nix b/checkmate/modules/tests/transpose_swap.nix new file mode 100644 index 0000000..485e64e --- /dev/null +++ b/checkmate/modules/tests/transpose_swap.nix @@ -0,0 +1,10 @@ +{ transpose, ... }: +{ + + flake.tests."test transpose swaps parent and child attrNames" = { + expr = transpose { a.b.c = 1; }; + expected = { + b.a.c = 1; + }; + }; +} diff --git a/checkmate/modules/tests/without_flakes.nix b/checkmate/modules/tests/without_flakes.nix new file mode 100644 index 0000000..6428e9b --- /dev/null +++ b/checkmate/modules/tests/without_flakes.nix @@ -0,0 +1,44 @@ +{ lib, targetLib, ... }: +{ + + flake.tests."test usage without flakes" = + let + flake-aspects-lib = import targetLib lib; + # first eval is like evaling the flake. + first = lib.evalModules { + modules = [ + (flake-aspects-lib.new-scope "hello") + { + hello.aspects = + { aspects, ... }: + { + a.b.c = [ "world" ]; + a.includes = [ aspects.x ]; + x.b = + { lib, ... }: + { + c = lib.splitString " " "mundo cruel"; + }; + }; + } + ]; + }; + # second eval is like evaling its nixosConfiguration + second = lib.evalModules { + modules = [ + { options.c = lib.mkOption { type = lib.types.listOf lib.types.str; }; } + first.config.hello.modules.b.a + ]; + }; + expr = lib.sort (a: b: a < b) second.config.c; + expected = [ + "cruel" + "mundo" + "world" + ]; + in + { + inherit expr expected; + }; + +} diff --git a/nix/types.nix b/nix/types.nix index b7c124c..ed2c5eb 100644 --- a/nix/types.nix +++ b/nix/types.nix @@ -5,7 +5,7 @@ let aspectsType = lib.types.submodule ( { config, ... }: { - freeformType = lib.types.attrsOf (lib.types.either aspectSubmoduleAttrs providerType); + freeformType = lib.types.attrsOf providerType; config._module.args.aspects = config; } ); @@ -30,7 +30,7 @@ let ); functionProviderType = lib.types.either functionToAspect (lib.types.functionTo providerType); - providerType = lib.types.either functionProviderType aspectSubmodule; + providerType = lib.types.either aspectSubmoduleAttrs functionProviderType; aspectSubmoduleAttrs = lib.types.addCheck aspectSubmodule ( m: (!builtins.isFunction m) || (isAspectSubmoduleFn m) @@ -78,13 +78,7 @@ let options.provides = lib.mkOption { description = "Providers of aspect for other aspects"; default = { }; - type = lib.types.submodule ( - { config, ... }: - { - freeformType = lib.types.attrsOf providerType; - config._module.args.provides = config; - } - ); + type = aspectsType; }; options.__functor = lib.mkOption { internal = true;