lib.modules: add tests for option valueMeta

This commit is contained in:
Johannes Kirschbauer
2025-03-20 16:20:03 +00:00
parent 644527dd57
commit 8fa33000a3
3 changed files with 148 additions and 0 deletions

View File

@@ -761,6 +761,19 @@ checkConfigOutput '"bar"' config.sub.conditionalImportAsNixos.foo ./specialArgs-
checkConfigError 'attribute .*bar.* not found' config.sub.conditionalImportAsNixos.bar ./specialArgs-class.nix
checkConfigError 'attribute .*foo.* not found' config.sub.conditionalImportAsDarwin.foo ./specialArgs-class.nix
checkConfigOutput '"foo"' config.sub.conditionalImportAsDarwin.bar ./specialArgs-class.nix
# Check that some types expose the 'valueMeta'
checkConfigOutput '\{\}' options.str.valueMeta ./types-valueMeta.nix
checkConfigOutput '["foo", "bar"]' config.attrsOfResult ./types-valueMeta.nix
checkConfigOutput '2' config.listOfResult ./types-valueMeta.nix
# Check that composed types expose the 'valueMeta'
# attrsOf submodule (also on merged options,types)
checkConfigOutput '42' options.attrsOfModule.valueMeta.attrs.foo.options.bar.value ./composed-types-valueMeta.nix
checkConfigOutput '42' options.mergedAttrsOfModule.valueMeta.attrs.foo.options.bar.value ./composed-types-valueMeta.nix
# listOf submodule (also on merged options,types)
checkConfigOutput '42' config.listResult ./composed-types-valueMeta.nix
checkConfigOutput '42' config.mergedListResult ./composed-types-valueMeta.nix
cat <<EOF
====== module tests ======

View File

@@ -0,0 +1,75 @@
{ lib, ... }:
let
inherit (lib) types mkOption;
attrsOfModule = mkOption {
type = types.attrsOf (
types.submodule {
options.bar = mkOption {
type = types.int;
};
}
);
};
listOfModule = mkOption {
type = types.listOf (
types.submodule {
options.bar = mkOption {
type = types.int;
};
}
);
};
in
{
imports = [
# Module A
({
options.attrsOfModule = attrsOfModule;
options.mergedAttrsOfModule = attrsOfModule;
options.listOfModule = listOfModule;
options.mergedListOfModule = listOfModule;
})
# Module B
({
options.mergedAttrsOfModule = attrsOfModule;
options.mergedListOfModule = listOfModule;
})
# Values
# It is important that the value is defined in a separate module
# Without valueMeta the actual value and sub-options wouldn't be accessible via:
# options.attrsOfModule.type.getSubOptions
({
attrsOfModule = {
foo.bar = 42;
};
mergedAttrsOfModule = {
foo.bar = 42;
};
})
(
{ options, ... }:
{
config.listOfModule = [
{
bar = 42;
}
];
config.mergedListOfModule = [
{
bar = 42;
}
];
# Result options to expose the list module to bash as plain attribute path
options.listResult = mkOption {
default = (builtins.head options.listOfModule.valueMeta.list).options.bar.value;
};
options.mergedListResult = mkOption {
default = (builtins.head options.mergedListOfModule.valueMeta.list).options.bar.value;
};
}
)
];
}

View File

@@ -0,0 +1,60 @@
{ lib, ... }:
let
inherit (lib) types mkOption;
inherit (types)
# attrsOf uses attrsWith internally
attrsOf
listOf
submoduleOf
str
;
in
{
imports = [
(
{ options, ... }:
{
# Should have an empty valueMeta
options.str = mkOption {
type = str;
};
# Should have some valueMeta which is an attribute set of the nested valueMeta
options.attrsOf = mkOption {
type = attrsOf str;
default = {
foo = "foo";
bar = "bar";
};
};
options.attrsOfResult = mkOption {
default = builtins.attrNames options.attrsOf.valueMeta.attrs;
};
# Should have some valueMeta which is the list of the nested valueMeta of types.str
# [ {} {} ]
options.listOf = mkOption {
type = listOf str;
default = [
"foo"
"bar"
];
};
options.listOfResult = mkOption {
default = builtins.length options.listOf.valueMeta.list;
};
# Should have some valueMeta which is the submodule evaluation
# { _module, options, config, ...}
options.submoduleOf = mkOption {
type = submoduleOf {
options.str = mkOption {
type = str;
};
};
};
}
)
];
}