From b081123bdc6342f7fd72d30a7a20f3427df9493d Mon Sep 17 00:00:00 2001 From: Victor Borja Date: Sun, 30 Nov 2025 18:50:54 -0600 Subject: [PATCH] split tests, reorg types Change-Id: vkpyrnzqtkmtwsuqwvkzttpnyrmynyrk --- .github/workflows/test.yml | 2 +- checkmate/flake.lock | 184 ++++++ checkmate/flake.nix | 28 + checkmate/modules/checkmate.nix | 25 + checkmate/modules/tests.nix | 573 ++---------------- checkmate/modules/tests/aspect_chain.nix | 53 ++ .../tests/aspect_default_provider_functor.nix | 53 ++ .../aspect_default_provider_override.nix | 43 ++ .../modules/tests/aspect_dependencies.nix | 37 ++ checkmate/modules/tests/aspect_fixpoint.nix | 59 ++ .../modules/tests/aspect_modules_resolved.nix | 54 ++ checkmate/modules/tests/aspect_parametric.nix | 34 ++ checkmate/modules/tests/aspect_provides.nix | 64 ++ .../tests/aspect_toplevel_parametric.nix | 42 ++ checkmate/modules/tests/default_empty.nix | 30 + .../modules/tests/tranpose_flake_modules.nix | 29 + checkmate/modules/tests/transpose_common.nix | 15 + checkmate/modules/tests/transpose_swap.nix | 10 + checkmate/modules/tests/without_flakes.nix | 44 ++ 19 files changed, 866 insertions(+), 513 deletions(-) create mode 100644 checkmate/flake.lock create mode 100644 checkmate/flake.nix create mode 100644 checkmate/modules/checkmate.nix create mode 100644 checkmate/modules/tests/aspect_chain.nix create mode 100644 checkmate/modules/tests/aspect_default_provider_functor.nix create mode 100644 checkmate/modules/tests/aspect_default_provider_override.nix create mode 100644 checkmate/modules/tests/aspect_dependencies.nix create mode 100644 checkmate/modules/tests/aspect_fixpoint.nix create mode 100644 checkmate/modules/tests/aspect_modules_resolved.nix create mode 100644 checkmate/modules/tests/aspect_parametric.nix create mode 100644 checkmate/modules/tests/aspect_provides.nix create mode 100644 checkmate/modules/tests/aspect_toplevel_parametric.nix create mode 100644 checkmate/modules/tests/default_empty.nix create mode 100644 checkmate/modules/tests/tranpose_flake_modules.nix create mode 100644 checkmate/modules/tests/transpose_common.nix create mode 100644 checkmate/modules/tests/transpose_swap.nix create mode 100644 checkmate/modules/tests/without_flakes.nix diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 70602ce..f7d582d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,4 +8,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: cachix/install-nix-action@v30 - - run: nix flake check -L github:vic/checkmate --override-input target github:$GITHUB_REPOSITORY/$GITHUB_SHA + - run: nix flake check -L github:$GITHUB_REPOSITORY/$GITHUB_SHA?dir=checkmate --override-input target github:$GITHUB_REPOSITORY/$GITHUB_SHA diff --git a/checkmate/flake.lock b/checkmate/flake.lock new file mode 100644 index 0000000..c493ca5 --- /dev/null +++ b/checkmate/flake.lock @@ -0,0 +1,184 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs-lib" + ] + }, + "locked": { + "lastModified": 1763759067, + "narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "import-tree": { + "locked": { + "lastModified": 1763762820, + "narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=", + "owner": "vic", + "repo": "import-tree", + "rev": "3c23749d8013ec6daa1d7255057590e9ca726646", + "type": "github" + }, + "original": { + "owner": "vic", + "repo": "import-tree", + "type": "github" + } + }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "nix-unit", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1737420293, + "narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, + "nix-unit": { + "inputs": { + "flake-parts": [ + "flake-parts" + ], + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "nixpkgs" + ], + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1762774186, + "narHash": "sha256-hRADkHjNt41+JUHw2EiSkMaL4owL83g5ZppjYUdF/Dc=", + "owner": "nix-community", + "repo": "nix-unit", + "rev": "1c9ab50554eed0b768f9e5b6f646d63c9673f0f7", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-unit", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1764587062, + "narHash": "sha256-hdFa0TAVQAQLDF31cEW3enWmBP+b592OvHs6WVe3D8k=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "c1cb7d097cb250f6e1904aacd5f2ba5ffd8a49ce", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "import-tree": "import-tree", + "nix-unit": "nix-unit", + "nixpkgs": "nixpkgs", + "nixpkgs-lib": [ + "nixpkgs" + ], + "systems": "systems", + "target": "target", + "treefmt-nix": "treefmt-nix_2" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "target": { + "locked": { + "path": "..", + "type": "path" + }, + "original": { + "path": "..", + "type": "path" + }, + "parent": [] + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nix-unit", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1762410071, + "narHash": "sha256-aF5fvoZeoXNPxT0bejFUBXeUjXfHLSL7g+mjR/p5TEg=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "97a30861b13c3731a84e09405414398fbf3e109f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "treefmt-nix_2": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1762938485, + "narHash": "sha256-AlEObg0syDl+Spi4LsZIBrjw+snSVU4T8MOeuZJUJjM=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "5b4ee75aeefd1e2d5a1cc43cf6ba65eba75e83e4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/checkmate/flake.nix b/checkmate/flake.nix new file mode 100644 index 0000000..f46efc7 --- /dev/null +++ b/checkmate/flake.nix @@ -0,0 +1,28 @@ +{ + + outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules); + + inputs = { + target.url = "path:.."; + flake-parts = { + inputs.nixpkgs-lib.follows = "nixpkgs-lib"; + url = "github:hercules-ci/flake-parts"; + }; + import-tree.url = "github:vic/import-tree"; + nix-unit = { + inputs = { + flake-parts.follows = "flake-parts"; + nixpkgs.follows = "nixpkgs"; + }; + url = "github:nix-community/nix-unit"; + }; + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + nixpkgs-lib.follows = "nixpkgs"; + systems.url = "github:nix-systems/default"; + treefmt-nix = { + inputs.nixpkgs.follows = "nixpkgs"; + url = "github:numtide/treefmt-nix"; + }; + }; + +} diff --git a/checkmate/modules/checkmate.nix b/checkmate/modules/checkmate.nix new file mode 100644 index 0000000..649332c --- /dev/null +++ b/checkmate/modules/checkmate.nix @@ -0,0 +1,25 @@ +{ inputs, lib, ... }: +{ + imports = [ + inputs.nix-unit.modules.flake.default + inputs.treefmt-nix.flakeModule + ]; + systems = import inputs.systems; + + perSystem = + { self', ... }: + { + packages.fmt = self'.formatter; + treefmt.projectRoot = inputs.target; + nix-unit = { + allowNetwork = true; + inputs = inputs; + }; + treefmt.programs = { + nixfmt.enable = true; + }; + treefmt.settings.global.excludes = [ + "LICENSE" + ]; + }; +} 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..daeb26f --- /dev/null +++ b/checkmate/modules/tests/aspect_default_provider_override.nix @@ -0,0 +1,43 @@ +{ + mkFlake, + evalMod, + lib, + ... +}: +{ + + 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..2757d7a --- /dev/null +++ b/checkmate/modules/tests/aspect_fixpoint.nix @@ -0,0 +1,59 @@ +{ + lib, + mkFlake, + evalMod, + fooOpt, + ... +}: +{ + + 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..44a6bf7 --- /dev/null +++ b/checkmate/modules/tests/aspect_provides.nix @@ -0,0 +1,64 @@ +{ + lib, + mkFlake, + evalMod, + fooOpt, + ... +}: +{ + + 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..92544ab --- /dev/null +++ b/checkmate/modules/tests/aspect_toplevel_parametric.nix @@ -0,0 +1,42 @@ +{ + mkFlake, + evalMod, + lib, + ... +}: +{ + + 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..6588713 --- /dev/null +++ b/checkmate/modules/tests/default_empty.nix @@ -0,0 +1,30 @@ +{ + lib, + 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..f42332b --- /dev/null +++ b/checkmate/modules/tests/tranpose_flake_modules.nix @@ -0,0 +1,29 @@ +{ + mkFlake, + lib, + 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; + }; + +} -- 2.43.0